<!DOCTYPE HTML>
<html lang="en">
<head>
<title>Spring Data JDBC - Preface | Docs4dev</title>
<meta charset="UTF-8">
<meta content="text/html; charset=utf-8" http-equiv="Content-Type">
<meta name="description" content="Spring Data JDBC, part of the larger Spring Data family, makes it easy to implement JDBC based repositories. This module deals with enhanced support for JDBC based data access layers. It makes it easier to build Spring powered applications that use data access technologies.">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="HandheldFriendly" content="true">
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black">
<meta property="og:type" content="website">
<meta property="og:title" content="Spring Data JDBC - Preface">
<meta property="og:url" content="https://www.docs4dev.com/docs/en/spring-data-jdbc/1.0.5.RELEASE/reference/">
<meta property="og:site_name" content="Docs4dev">
<meta property="og:locale" content="zh_CN">
<meta name="twitter:card" content="Spring Data JDBC, part of the larger Spring Data family, makes it easy to implement JDBC based repositories. This module deals with enhanced support for JDBC based data access layers. It makes it easier to build Spring powered applications that use data access technologies.">
<meta name="generator" content="Docs4dev template engine">
<link rel="stylesheet" href="static/css/app.min.css">
<link rel="shortcut icon" href="https://www.docs4dev.com/static/images/favicon.ico" type="image/x-icon">
<script async="" src="static/js/js.js"></script>
<script async="" src="static/js/adsbygoogle.js" crossorigin="anonymous"></script>
<script>
    window.dataLayer = window.dataLayer || [];

    function gtag() {
      dataLayer.push(arguments);
    }

    gtag('js', new Date());
    gtag('config', 'UA-129571937-1');
  </script>
<link rel="amphtml" href="https://www.docs4dev.com/amp/docs/en/spring-data-jdbc/1.0.5.RELEASE/reference/index.html">

<script type="application/ld+json">{"name":null,"headline":"Spring Data JDBC-Preface","inLanguage":"en-US","version":"1.0.5.RELEASE","image":"/static/icon/icon-spring-data.png","datePublished":"2021-05-20T12:51:01Z","dateCreated":"2021-05-20T12:51:01Z","dateModified":"2021-07-03T12:24:35Z","@context":"https://schema.org/","@type":"APIReference","abstract":"Spring Data JDBC, part of the larger Spring Data family, makes it easy to implement JDBC based repositories. This module deals with enhanced support for JDBC based data access layers. It makes it easier to build Spring powered applications that use data access technologies."}</script>
</head>
<body>
<div class="book with-summary">
<div class="book-summary">
<div class="logo">
<a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-jdbc/1.0.5.RELEASE/reference');" style="color: inherit;">
<img src="static/picture/icon-spring-data.png" style="width: 48px; height: 48px;" alt="Logo">
</a>
<b style="color: inherit; margin-left: 8px;">Spring Data JDBC</b>
</div>
<div class="item">
<div>
<label for="version">版本</label>
<select id="version" onchange="onVersionChange(this)">
<option value="1.0.5.RELEASE" selected="selected">1.0.5.RELEASE</option>
</select>
</div>
<div style="margin-top: 8px;">
<label for="language">语言</label>
<select id="language" onchange="onLangChange(this)" value="en">
<option value="en" selected="selected">English</option>
<option value="zh">中文</option>
</select>
</div>

</div>
<div class="item menus">
<a title="Table of Contents" style="margin-right: 8px;" href="#">
<i class="fa fa-chevron-left"></i>
<span style="margin-left: 2px;">返回目录</span>
</a>
</div>
<nav role="navigation" id="navigation">
<ul class="summary">
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-jdbc/1.0.5.RELEASE/reference/all.html#preface');" title="Preface"> Preface </a>
<ul class="articles">
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-jdbc/1.0.5.RELEASE/reference/all.html#project');" title="Project Metadata"> Project Metadata </a> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-jdbc/1.0.5.RELEASE/reference/all.html#new-features');" title="1. New &amp; Noteworthy"> 1. New &amp; Noteworthy </a>
<ul class="articles">
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-jdbc/1.0.5.RELEASE/reference/all.html#new-features.1-0-0');" title="1.1. What’s New in Spring Data JDBC 1.0"> 1.1. What’s New in Spring Data JDBC 1.0 </a> </li>
</ul> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-jdbc/1.0.5.RELEASE/reference/all.html#dependencies');" title="2. Dependencies"> 2. Dependencies </a>
<ul class="articles">
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-jdbc/1.0.5.RELEASE/reference/all.html#dependencies.spring-boot');" title="2.1. Dependency Management with Spring Boot"> 2.1. Dependency Management with Spring Boot </a> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-jdbc/1.0.5.RELEASE/reference/all.html#dependencies.spring-framework');" title="2.2. Spring Framework"> 2.2. Spring Framework </a> </li>
</ul> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-jdbc/1.0.5.RELEASE/reference/all.html#repositories');" title="3. Working with Spring Data Repositories"> 3. Working with Spring Data Repositories </a>
<ul class="articles">
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-jdbc/1.0.5.RELEASE/reference/all.html#repositories.core-concepts');" title="3.1. Core concepts"> 3.1. Core concepts </a> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-jdbc/1.0.5.RELEASE/reference/all.html#repositories.query-methods');" title="3.2. Query methods"> 3.2. Query methods </a> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-jdbc/1.0.5.RELEASE/reference/all.html#repositories.definition');" title="3.3. Defining Repository Interfaces"> 3.3. Defining Repository Interfaces </a>
<ul class="articles">
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-jdbc/1.0.5.RELEASE/reference/all.html#repositories.definition-tuning');" title="3.3.1. Fine-tuning Repository Definition"> 3.3.1. Fine-tuning Repository Definition </a> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-jdbc/1.0.5.RELEASE/reference/all.html#repositories.multiple-modules');" title="3.3.2. Using Repositories with Multiple Spring Data Modules"> 3.3.2. Using Repositories with Multiple Spring Data Modules </a> </li>
</ul> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-jdbc/1.0.5.RELEASE/reference/all.html#repositories.query-methods.details');" title="3.4. Defining Query Methods"> 3.4. Defining Query Methods </a>
<ul class="articles">
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-jdbc/1.0.5.RELEASE/reference/all.html#repositories.query-methods.query-lookup-strategies');" title="3.4.1. Query Lookup Strategies"> 3.4.1. Query Lookup Strategies </a> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-jdbc/1.0.5.RELEASE/reference/all.html#repositories.query-methods.query-creation');" title="3.4.2. Query Creation"> 3.4.2. Query Creation </a> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-jdbc/1.0.5.RELEASE/reference/all.html#repositories.query-methods.query-property-expressions');" title="3.4.3. Property Expressions"> 3.4.3. Property Expressions </a> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-jdbc/1.0.5.RELEASE/reference/all.html#repositories.special-parameters');" title="3.4.4. Special parameter handling"> 3.4.4. Special parameter handling </a> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-jdbc/1.0.5.RELEASE/reference/all.html#repositories.limit-query-result');" title="3.4.5. Limiting Query Results"> 3.4.5. Limiting Query Results </a> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-jdbc/1.0.5.RELEASE/reference/all.html#repositories.collections-and-iterables');" title="3.4.6. Repository Methods Returning Collections or Iterables"> 3.4.6. Repository Methods Returning Collections or Iterables </a> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-jdbc/1.0.5.RELEASE/reference/all.html#repositories.nullability');" title="3.4.7. Null Handling of Repository Methods"> 3.4.7. Null Handling of Repository Methods </a> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-jdbc/1.0.5.RELEASE/reference/all.html#repositories.query-streaming');" title="3.4.8. Streaming query results"> 3.4.8. Streaming query results </a> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-jdbc/1.0.5.RELEASE/reference/all.html#repositories.query-async');" title="3.4.9. Async query results"> 3.4.9. Async query results </a> </li>
</ul> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-jdbc/1.0.5.RELEASE/reference/all.html#repositories.create-instances');" title="3.5. Creating Repository Instances"> 3.5. Creating Repository Instances </a>
<ul class="articles">
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-jdbc/1.0.5.RELEASE/reference/all.html#repositories.create-instances.spring');" title="3.5.1. XML configuration"> 3.5.1. XML configuration </a> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-jdbc/1.0.5.RELEASE/reference/all.html#repositories.create-instances.java-config');" title="3.5.2. JavaConfig"> 3.5.2. JavaConfig </a> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-jdbc/1.0.5.RELEASE/reference/all.html#repositories.create-instances.standalone');" title="3.5.3. Standalone usage"> 3.5.3. Standalone usage </a> </li>
</ul> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-jdbc/1.0.5.RELEASE/reference/all.html#repositories.custom-implementations');" title="3.6. Custom Implementations for Spring Data Repositories"> 3.6. Custom Implementations for Spring Data Repositories </a>
<ul class="articles">
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-jdbc/1.0.5.RELEASE/reference/all.html#repositories.single-repository-behavior');" title="3.6.1. Customizing Individual Repositories"> 3.6.1. Customizing Individual Repositories </a> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-jdbc/1.0.5.RELEASE/reference/all.html#repositories.customize-base-repository');" title="3.6.2. Customize the Base Repository"> 3.6.2. Customize the Base Repository </a> </li>
</ul> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-jdbc/1.0.5.RELEASE/reference/all.html#core.domain-events');" title="3.7. Publishing Events from Aggregate Roots"> 3.7. Publishing Events from Aggregate Roots </a> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-jdbc/1.0.5.RELEASE/reference/all.html#core.extensions');" title="3.8. Spring Data Extensions"> 3.8. Spring Data Extensions </a>
<ul class="articles">
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-jdbc/1.0.5.RELEASE/reference/all.html#core.extensions.querydsl');" title="3.8.1. Querydsl Extension"> 3.8.1. Querydsl Extension </a> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-jdbc/1.0.5.RELEASE/reference/all.html#core.web');" title="3.8.2. Web support"> 3.8.2. Web support </a> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-jdbc/1.0.5.RELEASE/reference/all.html#core.repository-populators');" title="3.8.3. Repository Populators"> 3.8.3. Repository Populators </a> </li>
</ul> </li>
</ul> </li>
</ul> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-jdbc/1.0.5.RELEASE/reference/all.html#reference');" title="Reference Documentation"> Reference Documentation </a>
<ul class="articles">
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-jdbc/1.0.5.RELEASE/reference/all.html#jdbc.repositories');" title="4. JDBC Repositories"> 4. JDBC Repositories </a> </li>
</ul> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-jdbc/1.0.5.RELEASE/reference/all.html#appendix');" title="Appendix"> Appendix </a>
<ul class="articles">
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-jdbc/1.0.5.RELEASE/reference/all.html#faq');" title="Appendix A: Frequently Asked Questions"> Appendix A: Frequently Asked Questions </a> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-jdbc/1.0.5.RELEASE/reference/all.html#glossary');" title="Appendix B: Glossary"> Appendix B: Glossary </a> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-jdbc/1.0.5.RELEASE/reference/all.html#repositories.namespace-reference');" title="Appendix C: Namespace reference"> Appendix C: Namespace reference </a>
<ul class="articles">
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-jdbc/1.0.5.RELEASE/reference/all.html#populator.namespace-dao-config');" title="The <repositories /> Element"> The &lt;repositories /&gt; Element </a> </li>
</ul> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-jdbc/1.0.5.RELEASE/reference/all.html#populator.namespace-reference');" title="Appendix D: Populators namespace reference"> Appendix D: Populators namespace reference </a>
<ul class="articles">
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-jdbc/1.0.5.RELEASE/reference/all.html#namespace-dao-config');" title="The <populator /> element"> The &lt;populator /&gt; element </a> </li>
</ul> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-jdbc/1.0.5.RELEASE/reference/all.html#repository-query-keywords');" title="Appendix E: Repository query keywords"> Appendix E: Repository query keywords </a>
<ul class="articles">
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-jdbc/1.0.5.RELEASE/reference/all.html#_supported_query_keywords');" title="Supported query keywords"> Supported query keywords </a> </li>
</ul> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-jdbc/1.0.5.RELEASE/reference/all.html#repository-query-return-types');" title="Appendix F: Repository query return types"> Appendix F: Repository query return types </a>
<ul class="articles">
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-jdbc/1.0.5.RELEASE/reference/all.html#_supported_query_return_types');" title="Supported Query Return Types"> Supported Query Return Types </a> </li>
</ul> </li>
</ul> </li>
</ul>
</nav>
</div>
<div class="book-body">
<div class="body-inner">
<header class="book-header">
<div class="dropdown pull-right js-toolbar-action">
<a class="btn toggle-dropdown" aria-label="Language" href="#">
<i class="fa fa-globe"></i>
</a>
<div class="dropdown-menu dropdown-left">
<div class="dropdown-caret"><span class="caret-outer"></span><span class="caret-inner"></span></div>
<div class="buttons">
<button class="button size-1" onclick="changeLang('zh_CN')">中文</button>
</div>
<div class="buttons">
<button class="button size-1" onclick="changeLang('en_US')">English</button>
</div>
</div>
</div>
<a class="btn pull-right js-toolbar-action non-mobile" aria-label="Sign up" href="register.html">
<i class="fa fa-sign-in"></i> <span>注册</span>
</a>
<a class="btn pull-right js-toolbar-action non-mobile" aria-label="Sign in" href="register.html">
<i class="fa fa-sign-in"></i>
<span>登录</span>
</a>
<a class="btn pull-left js-toolbar-action btn-summary" href="#"><i class="fa fa-align-justify"></i></a>
<div class="dropdown pull-left font-settings js-toolbar-action">
<a class="btn toggle-dropdown" aria-label="Font Settings" href="#">
<i class="fa fa-font"></i>
</a>
<div class="dropdown-menu dropdown-right">
<div class="dropdown-caret"><span class="caret-outer"></span><span class="caret-inner"></span></div>
<div class="buttons">
<button class="button size-2 font-reduce">A</button>
<button class="button size-2 font-enlarge">A</button>
</div>
<div class="buttons">
<button class="button size-2 family-serif">Serif</button>
<button class="button size-2 family-sans">Sans</button>
</div>
<div class="buttons">
<button class="button size-3 theme-white">White</button>
<button class="button size-3 theme-sepia">Sepia</button>
<button class="button size-3 theme-night">Night</button>
</div>
</div>
</div>
<a class="btn pull-left js-toolbar-action non-mobile" aria-label="Home" href="en.html">
<i class="fa fa-home"></i> <span>首页</span>
</a>
<a class="btn pull-left js-toolbar-action non-mobile" aria-label="Guide" href="javascript:window.open('https://www.javadoc.org/');">
<i class="fa fa-book"></i> <span>API Docs</span>
</a>
<a class="btn pull-left js-toolbar-action non-mobile" aria-label="Tools" href="index37.html">
<i class="fa fa-gears"></i> <span>工具</span>
</a>
<div class="dropdown pull-left js-toolbar-action mobile">
<a class="btn toggle-dropdown" aria-label="Language" href="#">
<i class="fa fa-chevron-down"></i>
</a>
<div class="dropdown-menu dropdown-right">
<div class="dropdown-caret"><span class="caret-outer"></span><span class="caret-inner"></span></div>
<div class="buttons">
<a class="button size-1" aria-label="Home" href="en.html">
<i class="fa fa-home"></i> <span>首页</span>
</a>
</div>
<div class="buttons">
<a class="button size-1" aria-label="Guide" href="javascript:window.open('https://www.javadoc.org/');">
<i class="fa fa-book"></i> <span>API Docs</span>
</a>
</div>
<div class="buttons">
<a class="button size-1" aria-label="Tools" href="index37.html">
<i class="fa fa-gears"></i> <span>工具</span>
</a>
</div>
</div>
</div>
<div id="autocomplete" class="pull-right"></div>
<span id="toolbar-title"></span>
</header>
<div class="page-wrapper" tabindex="-1" role="main">
<div class="page-inner">
<section class="normal markdown-section">
<div id="content">
<h1>Preface</h1>
<div><ins class="adsbygoogle" style="display:block; text-align:center;" data-ad-layout="in-article" data-ad-format="fluid" data-ad-client="ca-pub-6108808167664152" data-ad-slot="6964403648"></ins>
<script>
(adsbygoogle = window.adsbygoogle || []).push({});
</script></div>
<div><div id="preamble">
<div class="sectionbody">
<div class="paragraph">
<p>© 2018-2019 The original authors.</p>
</div>
<div class="admonitionblock note">
<table>
<tbody>
<tr>
<td class="icon"> <i class="fa icon-note" title="Note"></i> </td>
<td class="content"> Copies of this document may be made for your own use and for distribution to others, provided that you do not charge any fee for such copies and further provided that each copy contains this Copyright Notice, whether distributed in print or electronically. </td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<div class="openblock partintro">
<div class="content">
Spring Data JDBC offers a repository abstraction based on JDBC.
</div>
</div>
<div class="sect1">
<h2 id="project"><a class="anchor" href="#project"></a>Project Metadata</h2>
<div class="sectionbody">
<div class="ulist">
<ul>
<li> <p>Version control: <a href="javascript:window.open('https://github.com/spring-projects/spring-data-jdbc');" class="bare" target="_blank" rel="noopener noreferrer">http://github.com/spring-projects/spring-data-jdbc <i class="fa fa-external-link"></i></a></p> </li>
<li> <p>Bugtracker: <a href="javascript:window.open('https://jira.spring.io/browse/DATAJDBC');" class="bare" target="_blank" rel="noopener noreferrer">https://jira.spring.io/browse/DATAJDBC <i class="fa fa-external-link"></i></a></p> </li>
<li> <p>Release repository: <a href="javascript:window.open('https://repo.spring.io/libs-release');" class="bare" target="_blank" rel="noopener noreferrer">https://repo.spring.io/libs-release <i class="fa fa-external-link"></i></a></p> </li>
<li> <p>Milestone repository: <a href="javascript:window.open('https://repo.spring.io/libs-milestone');" class="bare" target="_blank" rel="noopener noreferrer">https://repo.spring.io/libs-milestone <i class="fa fa-external-link"></i></a></p> </li>
<li> <p>Snapshot repository: <a href="javascript:window.open('https://repo.spring.io/libs-snapshot');" class="bare" target="_blank" rel="noopener noreferrer">https://repo.spring.io/libs-snapshot <i class="fa fa-external-link"></i></a></p> </li>
</ul>
</div>
</div>
</div>
<div class="sect1">
<h2 id="new-features"><a class="anchor" href="#new-features"></a>1. New &amp; Noteworthy</h2>
<div class="sectionbody">
<div class="paragraph">
<p>This section covers the significant changes for each version.</p>
</div>
<div class="sect2">
<h3 id="new-features.1-0-0"><a class="anchor" href="#new-features.1-0-0"></a>1.1. What’s New in Spring Data JDBC 1.0</h3>
<div class="ulist">
<ul>
<li> <p>Basic support for <code class="notranslate">CrudRepository</code>.</p> </li>
<li> <p><code class="notranslate">@Query</code> support.</p> </li>
<li> <p>MyBatis support.</p> </li>
<li> <p>Id generation.</p> </li>
<li> <p>Event support.</p> </li>
<li> <p>Auditing.</p> </li>
<li> <p><code class="notranslate">CustomConversions</code>.</p> </li>
</ul>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="dependencies"><a class="anchor" href="#dependencies"></a>2. Dependencies</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Due to the different inception dates of individual Spring Data modules, most of them carry different major and minor version numbers. The easiest way to find compatible ones is to rely on the Spring Data Release Train BOM that we ship with the compatible versions defined. In a Maven project, you would declare this dependency in the <code class="notranslate">&lt;dependencyManagement /&gt;</code> section of your POM, as follows:</p>
</div>
<div class="exampleblock">
<div class="title">
Example 1. Using the Spring Data release train BOM
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight notranslate"><code class="language-xml" data-lang="xml">&lt;dependencyManagement&gt;
  &lt;dependencies&gt;
    &lt;dependency&gt;
      &lt;groupId&gt;org.springframework.data&lt;/groupId&gt;
      &lt;artifactId&gt;spring-data-releasetrain&lt;/artifactId&gt;
      &lt;version&gt;Lovelace-SR5&lt;/version&gt;
      &lt;scope&gt;import&lt;/scope&gt;
      &lt;type&gt;pom&lt;/type&gt;
    &lt;/dependency&gt;
  &lt;/dependencies&gt;
&lt;/dependencyManagement&gt;</code></pre>
</div>
</div>
</div>
</div>
<div id="dependencies.train-names" class="paragraph">
<p>The current release train version is <code class="notranslate">Lovelace-SR5</code>. The train names ascend alphabetically and the currently available trains are listed <a href="javascript:window.open('https://github.com/spring-projects/spring-data-commons/wiki/Release-planning');" target="_blank" rel="noopener noreferrer">here <i class="fa fa-external-link"></i></a>. The version name follows the following pattern: <code class="notranslate">${name}-${release}</code>, where release can be one of the following:</p>
</div>
<div class="ulist">
<ul>
<li> <p><code class="notranslate">BUILD-SNAPSHOT</code>: Current snapshots</p> </li>
<li> <p><code class="notranslate">M1</code>, <code class="notranslate">M2</code>, and so on: Milestones</p> </li>
<li> <p><code class="notranslate">RC1</code>, <code class="notranslate">RC2</code>, and so on: Release candidates</p> </li>
<li> <p><code class="notranslate">RELEASE</code>: GA release</p> </li>
<li> <p><code class="notranslate">SR1</code>, <code class="notranslate">SR2</code>, and so on: Service releases</p> </li>
</ul>
</div>
<div class="paragraph">
<p>A working example of using the BOMs can be found in our <a href="javascript:window.open('https://github.com/spring-projects/spring-data-examples/tree/master/bom');" target="_blank" rel="noopener noreferrer">Spring Data examples repository <i class="fa fa-external-link"></i></a>. With that in place, you can declare the Spring Data modules you would like to use without a version in the <code class="notranslate">&lt;dependencies /&gt;</code> block, as follows:</p>
</div>
<div class="exampleblock">
<div class="title">
Example 2. Declaring a dependency to a Spring Data module
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight notranslate"><code class="language-xml" data-lang="xml">&lt;dependencies&gt;
  &lt;dependency&gt;
    &lt;groupId&gt;org.springframework.data&lt;/groupId&gt;
    &lt;artifactId&gt;spring-data-jpa&lt;/artifactId&gt;
  &lt;/dependency&gt;
&lt;dependencies&gt;</code></pre>
</div>
</div>
</div>
</div>
<div class="sect2">
<h3 id="dependencies.spring-boot"><a class="anchor" href="#dependencies.spring-boot"></a>2.1. Dependency Management with Spring Boot</h3>
<div class="paragraph">
<p>Spring Boot selects a recent version of Spring Data modules for you. If you still want to upgrade to a newer version, configure the property <code class="notranslate">spring-data-releasetrain.version</code> to the <a href="#dependencies.train-names">train name and iteration</a> you would like to use.</p>
</div>
</div>
<div class="sect2">
<h3 id="dependencies.spring-framework"><a class="anchor" href="#dependencies.spring-framework"></a>2.2. Spring Framework</h3>
<div class="paragraph">
<p>The current version of Spring Data modules require Spring Framework in version 5.1.5.RELEASE or better. The modules might also work with an older bugfix version of that minor version. However, using the most recent version within that generation is highly recommended.</p>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="repositories"><a class="anchor" href="#repositories"></a>3. Working with Spring Data Repositories</h2>
<div class="sectionbody">
<div class="paragraph">
<p>The goal of the Spring Data repository abstraction is to significantly reduce the amount of boilerplate code required to implement data access layers for various persistence stores.</p>
</div>
<div class="admonitionblock important">
<table>
<tbody>
<tr>
<td class="icon"> <i class="fa icon-important" title="Important"></i> </td>
<td class="content">
<div class="paragraph">
<p><em>Spring Data repository documentation and your module</em></p>
</div>
<div class="paragraph">
<p>This chapter explains the core concepts and interfaces of Spring Data repositories. The information in this chapter is pulled from the Spring Data Commons module. It uses the configuration and code samples for the Java Persistence API (JPA) module. You should adapt the XML namespace declaration and the types to be extended to the equivalents of the particular module that you use. “<a href="#repositories.namespace-reference">Namespace reference</a>” covers XML configuration, which is supported across all Spring Data modules supporting the repository API. “<a href="#repository-query-keywords">Repository query keywords</a>” covers the query method keywords supported by the repository abstraction in general. For detailed information on the specific features of your module, see the chapter on that module of this document.</p>
</div> </td>
</tr>
</tbody>
</table>
</div>
<div class="sect2">
<h3 id="repositories.core-concepts"><a class="anchor" href="#repositories.core-concepts"></a>3.1. Core concepts</h3>
<div class="paragraph">
<p>The central interface in the Spring Data repository abstraction is <code class="notranslate">Repository</code>. It takes the domain class to manage as well as the ID type of the domain class as type arguments. This interface acts primarily as a marker interface to capture the types to work with and to help you to discover interfaces that extend this one. The <code class="notranslate">CrudRepository</code> provides sophisticated CRUD functionality for the entity class that is being managed.</p>
</div>
<div id="repositories.repository" class="exampleblock">
<div class="title">
Example 3.
<code class="notranslate">CrudRepository</code> interface
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight notranslate"><code class="language-java" data-lang="java">public interface CrudRepository&lt;T, ID&gt; extends Repository&lt;T, ID&gt; {

  &lt;S extends T&gt; S save(S entity);      <i class="conum" data-value="1"></i><b>(1)</b>

  Optional&lt;T&gt; findById(ID primaryKey); <i class="conum" data-value="2"></i><b>(2)</b>

  Iterable&lt;T&gt; findAll();               <i class="conum" data-value="3"></i><b>(3)</b>

  long count();                        <i class="conum" data-value="4"></i><b>(4)</b>

  void delete(T entity);               <i class="conum" data-value="5"></i><b>(5)</b>

  boolean existsById(ID primaryKey);   <i class="conum" data-value="6"></i><b>(6)</b>

  // … more functionality omitted.
}</code></pre>
</div>
</div>
<div class="colist arabic">
<table>
<tbody>
<tr>
<td><i class="conum" data-value="1"></i><b class="notranslate">1</b></td>
<td>Saves the given entity.</td>
</tr>
<tr>
<td><i class="conum" data-value="2"></i><b class="notranslate">2</b></td>
<td>Returns the entity identified by the given ID.</td>
</tr>
<tr>
<td><i class="conum" data-value="3"></i><b class="notranslate">3</b></td>
<td>Returns all entities.</td>
</tr>
<tr>
<td><i class="conum" data-value="4"></i><b class="notranslate">4</b></td>
<td>Returns the number of entities.</td>
</tr>
<tr>
<td><i class="conum" data-value="5"></i><b class="notranslate">5</b></td>
<td>Deletes the given entity.</td>
</tr>
<tr>
<td><i class="conum" data-value="6"></i><b class="notranslate">6</b></td>
<td>Indicates whether an entity with the given ID exists.</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<div class="admonitionblock note">
<table>
<tbody>
<tr>
<td class="icon"> <i class="fa icon-note" title="Note"></i> </td>
<td class="content"> We also provide persistence technology-specific abstractions, such as <code class="notranslate">JpaRepository</code> or <code class="notranslate">MongoRepository</code>. Those interfaces extend <code class="notranslate">CrudRepository</code> and expose the capabilities of the underlying persistence technology in addition to the rather generic persistence technology-agnostic interfaces such as <code class="notranslate">CrudRepository</code>. </td>
</tr>
</tbody>
</table>
</div>
<div class="paragraph">
<p>On top of the <code class="notranslate">CrudRepository</code>, there is a <code class="notranslate">PagingAndSortingRepository</code> abstraction that adds additional methods to ease paginated access to entities:</p>
</div>
<div class="exampleblock">
<div class="title">
Example 4.
<code class="notranslate">PagingAndSortingRepository</code> interface
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight notranslate"><code class="language-java" data-lang="java">public interface PagingAndSortingRepository&lt;T, ID&gt; extends CrudRepository&lt;T, ID&gt; {

  Iterable&lt;T&gt; findAll(Sort sort);

  Page&lt;T&gt; findAll(Pageable pageable);
}</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<p>To access the second page of <code class="notranslate">User</code> by a page size of 20, you could do something like the following:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight notranslate"><code class="language-java" data-lang="java">PagingAndSortingRepository&lt;User, Long&gt; repository = // … get access to a bean
Page&lt;User&gt; users = repository.findAll(PageRequest.of(1, 20));</code></pre>
</div>
</div>
<div class="paragraph">
<p>In addition to query methods, query derivation for both count and delete queries is available. The following list shows the interface definition for a derived count query:</p>
</div>
<div class="exampleblock">
<div class="title">
Example 5. Derived Count Query
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight notranslate"><code class="language-java" data-lang="java">interface UserRepository extends CrudRepository&lt;User, Long&gt; {

  long countByLastname(String lastname);
}</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<p>The following list shows the interface definition for a derived delete query:</p>
</div>
<div class="exampleblock">
<div class="title">
Example 6. Derived Delete Query
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight notranslate"><code class="language-java" data-lang="java">interface UserRepository extends CrudRepository&lt;User, Long&gt; {

  long deleteByLastname(String lastname);

  List&lt;User&gt; removeByLastname(String lastname);
}</code></pre>
</div>
</div>
</div>
</div>
</div>
<div class="sect2">
<h3 id="repositories.query-methods"><a class="anchor" href="#repositories.query-methods"></a>3.2. Query methods</h3>
<div class="paragraph">
<p>Standard CRUD functionality repositories usually have queries on the underlying datastore. With Spring Data, declaring those queries becomes a four-step process:</p>
</div>
<div class="olist arabic">
<ol class="arabic">
<li> <p>Declare an interface extending Repository or one of its subinterfaces and type it to the domain class and ID type that it should handle, as shown in the following example:</p>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight notranslate"><code class="language-java" data-lang="java">interface PersonRepository extends Repository&lt;Person, Long&gt; { … }</code></pre>
</div>
</div> </li>
<li> <p>Declare query methods on the interface.</p>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight notranslate"><code class="language-java" data-lang="java">interface PersonRepository extends Repository&lt;Person, Long&gt; {
  List&lt;Person&gt; findByLastname(String lastname);
}</code></pre>
</div>
</div> </li>
<li> <p>Set up Spring to create proxy instances for those interfaces, either with <a href="#repositories.create-instances.java-config">JavaConfig</a> or with <a href="#repositories.create-instances">XML configuration</a>.</p>
<div class="olist loweralpha">
<ol class="loweralpha" type="a">
<li> <p>To use Java configuration, create a class similar to the following:</p>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight notranslate"><code class="language-java" data-lang="java">import org.springframework.data.jpa.repository.config.EnableJpaRepositories;

@EnableJpaRepositories
class Config { … }</code></pre>
</div>
</div> </li>
<li> <p>To use XML configuration, define a bean similar to the following:</p>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight notranslate"><code class="language-xml" data-lang="xml">&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;beans xmlns="http://www.springframework.org/schema/beans"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xmlns:jpa="http://www.springframework.org/schema/data/jpa"
   xsi:schemaLocation="http://www.springframework.org/schema/beans
     http://www.springframework.org/schema/beans/spring-beans.xsd
     http://www.springframework.org/schema/data/jpa
     http://www.springframework.org/schema/data/jpa/spring-jpa.xsd"&gt;

   &lt;jpa:repositories base-package="com.acme.repositories"/&gt;

&lt;/beans&gt;</code></pre>
</div>
</div> </li>
</ol>
</div>
<div class="paragraph">
<p>The JPA namespace is used in this example. If you use the repository abstraction for any other store, you need to change this to the appropriate namespace declaration of your store module. In other words, you should exchange <code class="notranslate">jpa</code> in favor of, for example, <code class="notranslate">mongodb</code>.</p>
</div>
<div class="paragraph">
<p>+ Also, note that the JavaConfig variant does not configure a package explicitly, because the package of the annotated class is used by default. To customize the package to scan, use one of the <code class="notranslate">basePackage…</code> attributes of the data-store-specific repository’s <code class="notranslate">@Enable${store}Repositories</code>-annotation.</p>
</div> </li>
<li> <p>Inject the repository instance and use it, as shown in the following example:</p>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight notranslate"><code class="language-java" data-lang="java">class SomeClient {

  private final PersonRepository repository;

  SomeClient(PersonRepository repository) {
    this.repository = repository;
  }

  void doSomething() {
    List&lt;Person&gt; persons = repository.findByLastname("Matthews");
  }
}</code></pre>
</div>
</div> </li>
</ol>
</div>
<div class="paragraph">
<p>The sections that follow explain each step in detail:</p>
</div>
<div class="ulist">
<ul>
<li> <p><a href="#repositories.definition">Defining Repository Interfaces</a></p> </li>
<li> <p><a href="#repositories.query-methods.details">Defining Query Methods</a></p> </li>
<li> <p><a href="#repositories.create-instances">Creating Repository Instances</a></p> </li>
<li> <p><a href="#repositories.custom-implementations">Custom Implementations for Spring Data Repositories</a></p> </li>
</ul>
</div>
</div>
<div class="sect2">
<h3 id="repositories.definition"><a class="anchor" href="#repositories.definition"></a>3.3. Defining Repository Interfaces</h3>
<div class="paragraph">
<p>First, define a domain class-specific repository interface. The interface must extend <code class="notranslate">Repository</code> and be typed to the domain class and an ID type. If you want to expose CRUD methods for that domain type, extend <code class="notranslate">CrudRepository</code> instead of <code class="notranslate">Repository</code>.</p>
</div>
<div class="sect3">
<h4 id="repositories.definition-tuning"><a class="anchor" href="#repositories.definition-tuning"></a>3.3.1. Fine-tuning Repository Definition</h4>
<div class="paragraph">
<p>Typically, your repository interface extends <code class="notranslate">Repository</code>, <code class="notranslate">CrudRepository</code>, or <code class="notranslate">PagingAndSortingRepository</code>. Alternatively, if you do not want to extend Spring Data interfaces, you can also annotate your repository interface with <code class="notranslate">@RepositoryDefinition</code>. Extending <code class="notranslate">CrudRepository</code> exposes a complete set of methods to manipulate your entities. If you prefer to be selective about the methods being exposed, copy the methods you want to expose from <code class="notranslate">CrudRepository</code> into your domain repository.</p>
</div>
<div class="admonitionblock note">
<table>
<tbody>
<tr>
<td class="icon"> <i class="fa icon-note" title="Note"></i> </td>
<td class="content"> Doing so lets you define your own abstractions on top of the provided Spring Data Repositories functionality. </td>
</tr>
</tbody>
</table>
</div>
<div class="paragraph">
<p>The following example shows how to selectively expose CRUD methods (<code class="notranslate">findById</code> and <code class="notranslate">save</code>, in this case):</p>
</div>
<div class="exampleblock">
<div class="title">
Example 7. Selectively exposing CRUD methods
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight notranslate"><code class="language-java" data-lang="java">@NoRepositoryBean
interface MyBaseRepository&lt;T, ID&gt; extends Repository&lt;T, ID&gt; {

  Optional&lt;T&gt; findById(ID id);

  &lt;S extends T&gt; S save(S entity);
}

interface UserRepository extends MyBaseRepository&lt;User, Long&gt; {
  User findByEmailAddress(EmailAddress emailAddress);
}</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<p>In the prior example, you defined a common base interface for all your domain repositories and exposed <code class="notranslate">findById(…)</code> as well as <code class="notranslate">save(…)</code>.These methods are routed into the base repository implementation of the store of your choice provided by Spring Data (for example, if you use JPA, the implementation is <code class="notranslate">SimpleJpaRepository</code>), because they match the method signatures in <code class="notranslate">CrudRepository</code>. So the <code class="notranslate">UserRepository</code> can now save users, find individual users by ID, and trigger a query to find <code class="notranslate">Users</code> by email address.</p>
</div>
<div class="admonitionblock note">
<table>
<tbody>
<tr>
<td class="icon"> <i class="fa icon-note" title="Note"></i> </td>
<td class="content"> The intermediate repository interface is annotated with <code class="notranslate">@NoRepositoryBean</code>. Make sure you add that annotation to all repository interfaces for which Spring Data should not create instances at runtime. </td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="sect3">
<h4 id="repositories.multiple-modules"><a class="anchor" href="#repositories.multiple-modules"></a>3.3.2. Using Repositories with Multiple Spring Data Modules</h4>
<div class="paragraph">
<p>Using a unique Spring Data module in your application makes things simple, because all repository interfaces in the defined scope are bound to the Spring Data module. Sometimes, applications require using more than one Spring Data module. In such cases, a repository definition must distinguish between persistence technologies. When it detects multiple repository factories on the class path, Spring Data enters strict repository configuration mode. Strict configuration uses details on the repository or the domain class to decide about Spring Data module binding for a repository definition:</p>
</div>
<div class="olist arabic">
<ol class="arabic">
<li> <p>If the repository definition <a href="#repositories.multiple-modules.types">extends the module-specific repository</a>, then it is a valid candidate for the particular Spring Data module.</p> </li>
<li> <p>If the domain class is <a href="#repositories.multiple-modules.annotations">annotated with the module-specific type annotation</a>, then it is a valid candidate for the particular Spring Data module. Spring Data modules accept either third-party annotations (such as JPA’s <code class="notranslate">@Entity</code>) or provide their own annotations (such as <code class="notranslate">@Document</code> for Spring Data MongoDB and Spring Data Elasticsearch).</p> </li>
</ol>
</div>
<div class="paragraph">
<p>The following example shows a repository that uses module-specific interfaces (JPA in this case):</p>
</div>
<div id="repositories.multiple-modules.types" class="exampleblock">
<div class="title">
Example 8. Repository definitions using module-specific interfaces
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight notranslate"><code class="language-java" data-lang="java">interface MyRepository extends JpaRepository&lt;User, Long&gt; { }

@NoRepositoryBean
interface MyBaseRepository&lt;T, ID&gt; extends JpaRepository&lt;T, ID&gt; { … }

interface UserRepository extends MyBaseRepository&lt;User, Long&gt; { … }</code></pre>
</div>
</div>
<div class="paragraph">
<p><code class="notranslate">MyRepository</code> and <code class="notranslate">UserRepository</code> extend <code class="notranslate">JpaRepository</code> in their type hierarchy. They are valid candidates for the Spring Data JPA module.</p>
</div>
</div>
</div>
<div class="paragraph">
<p>The following example shows a repository that uses generic interfaces:</p>
</div>
<div class="exampleblock">
<div class="title">
Example 9. Repository definitions using generic interfaces
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight notranslate"><code class="language-java" data-lang="java">interface AmbiguousRepository extends Repository&lt;User, Long&gt; { … }

@NoRepositoryBean
interface MyBaseRepository&lt;T, ID&gt; extends CrudRepository&lt;T, ID&gt; { … }

interface AmbiguousUserRepository extends MyBaseRepository&lt;User, Long&gt; { … }</code></pre>
</div>
</div>
<div class="paragraph">
<p><code class="notranslate">AmbiguousRepository</code> and <code class="notranslate">AmbiguousUserRepository</code> extend only <code class="notranslate">Repository</code> and <code class="notranslate">CrudRepository</code> in their type hierarchy. While this is perfectly fine when using a unique Spring Data module, multiple modules cannot distinguish to which particular Spring Data these repositories should be bound.</p>
</div>
</div>
</div>
<div class="paragraph">
<p>The following example shows a repository that uses domain classes with annotations:</p>
</div>
<div id="repositories.multiple-modules.annotations" class="exampleblock">
<div class="title">
Example 10. Repository definitions using domain classes with annotations
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight notranslate"><code class="language-java" data-lang="java">interface PersonRepository extends Repository&lt;Person, Long&gt; { … }

@Entity
class Person { … }

interface UserRepository extends Repository&lt;User, Long&gt; { … }

@Document
class User { … }</code></pre>
</div>
</div>
<div class="paragraph">
<p><code class="notranslate">PersonRepository</code> references <code class="notranslate">Person</code>, which is annotated with the JPA <code class="notranslate">@Entity</code> annotation, so this repository clearly belongs to Spring Data JPA. <code class="notranslate">UserRepository</code> references <code class="notranslate">User</code>, which is annotated with Spring Data MongoDB’s <code class="notranslate">@Document</code> annotation.</p>
</div>
</div>
</div>
<div class="paragraph">
<p>The following bad example shows a repository that uses domain classes with mixed annotations:</p>
</div>
<div class="exampleblock">
<div class="title">
Example 11. Repository definitions using domain classes with mixed annotations
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight notranslate"><code class="language-java" data-lang="java">interface JpaPersonRepository extends Repository&lt;Person, Long&gt; { … }

interface MongoDBPersonRepository extends Repository&lt;Person, Long&gt; { … }

@Entity
@Document
class Person { … }</code></pre>
</div>
</div>
<div class="paragraph">
<p>This example shows a domain class using both JPA and Spring Data MongoDB annotations. It defines two repositories, <code class="notranslate">JpaPersonRepository</code> and <code class="notranslate">MongoDBPersonRepository</code>. One is intended for JPA and the other for MongoDB usage. Spring Data is no longer able to tell the repositories apart, which leads to undefined behavior.</p>
</div>
</div>
</div>
<div class="paragraph">
<p><a href="#repositories.multiple-modules.types">Repository type details</a> and <a href="#repositories.multiple-modules.annotations">distinguishing domain class annotations</a> are used for strict repository configuration to identify repository candidates for a particular Spring Data module. Using multiple persistence technology-specific annotations on the same domain type is possible and enables reuse of domain types across multiple persistence technologies. However, Spring Data can then no longer determine a unique module with which to bind the repository.</p>
</div>
<div class="paragraph">
<p>The last way to distinguish repositories is by scoping repository base packages. Base packages define the starting points for scanning for repository interface definitions, which implies having repository definitions located in the appropriate packages. By default, annotation-driven configuration uses the package of the configuration class. The <a href="#repositories.create-instances.spring">base package in XML-based configuration</a> is mandatory.</p>
</div>
<div class="paragraph">
<p>The following example shows annotation-driven configuration of base packages:</p>
</div>
<div class="exampleblock">
<div class="title">
Example 12. Annotation-driven configuration of base packages
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight notranslate"><code class="language-java" data-lang="java">@EnableJpaRepositories(basePackages = "com.acme.repositories.jpa")
@EnableMongoRepositories(basePackages = "com.acme.repositories.mongo")
class Configuration { … }</code></pre>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="sect2">
<h3 id="repositories.query-methods.details"><a class="anchor" href="#repositories.query-methods.details"></a>3.4. Defining Query Methods</h3>
<div class="paragraph">
<p>The repository proxy has two ways to derive a store-specific query from the method name:</p>
</div>
<div class="ulist">
<ul>
<li> <p>By deriving the query from the method name directly.</p> </li>
<li> <p>By using a manually defined query.</p> </li>
</ul>
</div>
<div class="paragraph">
<p>Available options depend on the actual store. However, there must be a strategy that decides what actual query is created. The next section describes the available options.</p>
</div>
<div class="sect3">
<h4 id="repositories.query-methods.query-lookup-strategies"><a class="anchor" href="#repositories.query-methods.query-lookup-strategies"></a>3.4.1. Query Lookup Strategies</h4>
<div class="paragraph">
<p>The following strategies are available for the repository infrastructure to resolve the query. With XML configuration, you can configure the strategy at the namespace through the <code class="notranslate">query-lookup-strategy</code> attribute. For Java configuration, you can use the <code class="notranslate">queryLookupStrategy</code> attribute of the <code class="notranslate">Enable${store}Repositories</code> annotation. Some strategies may not be supported for particular datastores.</p>
</div>
<div class="ulist">
<ul>
<li> <p><code class="notranslate">CREATE</code> attempts to construct a store-specific query from the query method name. The general approach is to remove a given set of well known prefixes from the method name and parse the rest of the method. You can read more about query construction in “<a href="#repositories.query-methods.query-creation">Query Creation</a>”.</p> </li>
<li> <p><code class="notranslate">USE_DECLARED_QUERY</code> tries to find a declared query and throws an exception if cannot find one. The query can be defined by an annotation somewhere or declared by other means. Consult the documentation of the specific store to find available options for that store. If the repository infrastructure does not find a declared query for the method at bootstrap time, it fails.</p> </li>
<li> <p><code class="notranslate">CREATE_IF_NOT_FOUND</code> (default) combines <code class="notranslate">CREATE</code> and <code class="notranslate">USE_DECLARED_QUERY</code>. It looks up a declared query first, and, if no declared query is found, it creates a custom method name-based query. This is the default lookup strategy and, thus, is used if you do not configure anything explicitly. It allows quick query definition by method names but also custom-tuning of these queries by introducing declared queries as needed.</p> </li>
</ul>
</div>
</div>
<div class="sect3">
<h4 id="repositories.query-methods.query-creation"><a class="anchor" href="#repositories.query-methods.query-creation"></a>3.4.2. Query Creation</h4>
<div class="paragraph">
<p>The query builder mechanism built into Spring Data repository infrastructure is useful for building constraining queries over entities of the repository. The mechanism strips the prefixes <code class="notranslate">find…By</code>, <code class="notranslate">read…By</code>, <code class="notranslate">query…By</code>, <code class="notranslate">count…By</code>, and <code class="notranslate">get…By</code> from the method and starts parsing the rest of it. The introducing clause can contain further expressions, such as a <code class="notranslate">Distinct</code> to set a distinct flag on the query to be created. However, the first <code class="notranslate">By</code> acts as delimiter to indicate the start of the actual criteria. At a very basic level, you can define conditions on entity properties and concatenate them with <code class="notranslate">And</code> and <code class="notranslate">Or</code>. The following example shows how to create a number of queries:</p>
</div>
<div class="exampleblock">
<div class="title">
Example 13. Query creation from method names
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight notranslate"><code class="language-java" data-lang="java">interface PersonRepository extends Repository&lt;User, Long&gt; {

  List&lt;Person&gt; findByEmailAddressAndLastname(EmailAddress emailAddress, String lastname);

  // Enables the distinct flag for the query
  List&lt;Person&gt; findDistinctPeopleByLastnameOrFirstname(String lastname, String firstname);
  List&lt;Person&gt; findPeopleDistinctByLastnameOrFirstname(String lastname, String firstname);

  // Enabling ignoring case for an individual property
  List&lt;Person&gt; findByLastnameIgnoreCase(String lastname);
  // Enabling ignoring case for all suitable properties
  List&lt;Person&gt; findByLastnameAndFirstnameAllIgnoreCase(String lastname, String firstname);

  // Enabling static ORDER BY for a query
  List&lt;Person&gt; findByLastnameOrderByFirstnameAsc(String lastname);
  List&lt;Person&gt; findByLastnameOrderByFirstnameDesc(String lastname);
}</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<p>The actual result of parsing the method depends on the persistence store for which you create the query. However, there are some general things to notice:</p>
</div>
<div class="ulist">
<ul>
<li> <p>The expressions are usually property traversals combined with operators that can be concatenated. You can combine property expressions with <code class="notranslate">AND</code> and <code class="notranslate">OR</code>. You also get support for operators such as <code class="notranslate">Between</code>, <code class="notranslate">LessThan</code>, <code class="notranslate">GreaterThan</code>, and <code class="notranslate">Like</code> for the property expressions. The supported operators can vary by datastore, so consult the appropriate part of your reference documentation.</p> </li>
<li> <p>The method parser supports setting an <code class="notranslate">IgnoreCase</code> flag for individual properties (for example, <code class="notranslate">findByLastnameIgnoreCase(…)</code>) or for all properties of a type that supports ignoring case (usually <code class="notranslate">String</code> instances — for example, <code class="notranslate">findByLastnameAndFirstnameAllIgnoreCase(…)</code>). Whether ignoring cases is supported may vary by store, so consult the relevant sections in the reference documentation for the store-specific query method.</p> </li>
<li> <p>You can apply static ordering by appending an <code class="notranslate">OrderBy</code> clause to the query method that references a property and by providing a sorting direction (<code class="notranslate">Asc</code> or <code class="notranslate">Desc</code>). To create a query method that supports dynamic sorting, see “<a href="#repositories.special-parameters">Special parameter handling</a>”.</p> </li>
</ul>
</div>
 </div>
<div class="sect3">
<h4 id="repositories.query-methods.query-property-expressions"><a class="anchor" href="#repositories.query-methods.query-property-expressions"></a>3.4.3. Property Expressions</h4>
<div class="paragraph">
<p>Property expressions can refer only to a direct property of the managed entity, as shown in the preceding example. At query creation time, you already make sure that the parsed property is a property of the managed domain class. However, you can also define constraints by traversing nested properties. Consider the following method signature:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight notranslate"><code class="language-java" data-lang="java">List&lt;Person&gt; findByAddressZipCode(ZipCode zipCode);</code></pre>
</div>
</div>
<div class="paragraph">
<p>Assume a <code class="notranslate">Person</code> has an <code class="notranslate">Address</code> with a <code class="notranslate">ZipCode</code>. In that case, the method creates the property traversal <code class="notranslate">x.address.zipCode</code>. The resolution algorithm starts by interpreting the entire part (<code class="notranslate">AddressZipCode</code>) as the property and checks the domain class for a property with that name (uncapitalized). If the algorithm succeeds, it uses that property. If not, the algorithm splits up the source at the camel case parts from the right side into a head and a tail and tries to find the corresponding property — in our example, <code class="notranslate">AddressZip</code> and <code class="notranslate">Code</code>. If the algorithm finds a property with that head, it takes the tail and continues building the tree down from there, splitting the tail up in the way just described. If the first split does not match, the algorithm moves the split point to the left (<code class="notranslate">Address</code>, <code class="notranslate">ZipCode</code>) and continues.</p>
</div>
<div class="paragraph">
<p>Although this should work for most cases, it is possible for the algorithm to select the wrong property. Suppose the <code class="notranslate">Person</code> class has an <code class="notranslate">addressZip</code> property as well. The algorithm would match in the first split round already, choose the wrong property, and fail (as the type of <code class="notranslate">addressZip</code> probably has no <code class="notranslate">code</code> property).</p>
</div>
<div class="paragraph">
<p>To resolve this ambiguity you can use <code class="notranslate">_</code> inside your method name to manually define traversal points. So our method name would be as follows:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight notranslate"><code class="language-java" data-lang="java">List&lt;Person&gt; findByAddress_ZipCode(ZipCode zipCode);</code></pre>
</div>
</div>
<div class="paragraph">
<p>Because we treat the underscore character as a reserved character, we strongly advise following standard Java naming conventions (that is, not using underscores in property names but using camel case instead).</p>
</div>
</div>
<div class="sect3">
<h4 id="repositories.special-parameters"><a class="anchor" href="#repositories.special-parameters"></a>3.4.4. Special parameter handling</h4>
<div class="paragraph">
<p>To handle parameters in your query, define method parameters as already seen in the preceding examples. Besides that, the infrastructure recognizes certain specific types like <code class="notranslate">Pageable</code> and <code class="notranslate">Sort</code>, to apply pagination and sorting to your queries dynamically. The following example demonstrates these features:</p>
</div>
<div class="exampleblock">
<div class="title">
Example 14. Using
<code class="notranslate">Pageable</code>,
<code class="notranslate">Slice</code>, and
<code class="notranslate">Sort</code> in query methods
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight notranslate"><code class="language-java" data-lang="java">Page&lt;User&gt; findByLastname(String lastname, Pageable pageable);

Slice&lt;User&gt; findByLastname(String lastname, Pageable pageable);

List&lt;User&gt; findByLastname(String lastname, Sort sort);

List&lt;User&gt; findByLastname(String lastname, Pageable pageable);</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<p>The first method lets you pass an <code class="notranslate">org.springframework.data.domain.Pageable</code> instance to the query method to dynamically add paging to your statically defined query. A <code class="notranslate">Page</code> knows about the total number of elements and pages available. It does so by the infrastructure triggering a count query to calculate the overall number. As this might be expensive (depending on the store used), you can instead return a <code class="notranslate">Slice</code>. A <code class="notranslate">Slice</code> only knows about whether a next <code class="notranslate">Slice</code> is available, which might be sufficient when walking through a larger result set.</p>
</div>
<div class="paragraph">
<p>Sorting options are handled through the <code class="notranslate">Pageable</code> instance, too. If you only need sorting, add an <code class="notranslate">org.springframework.data.domain.Sort</code> parameter to your method. As you can see, returning a <code class="notranslate">List</code> is also possible. In this case, the additional metadata required to build the actual <code class="notranslate">Page</code> instance is not created (which, in turn, means that the additional count query that would have been necessary is not issued). Rather, it restricts the query to look up only the given range of entities.</p>
</div>
<div class="admonitionblock note">
<table>
<tbody>
<tr>
<td class="icon"> <i class="fa icon-note" title="Note"></i> </td>
<td class="content"> To find out how many pages you get for an entire query, you have to trigger an additional count query. By default, this query is derived from the query you actually trigger. </td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="sect3">
<h4 id="repositories.limit-query-result"><a class="anchor" href="#repositories.limit-query-result"></a>3.4.5. Limiting Query Results</h4>
<div class="paragraph">
<p>The results of query methods can be limited by using the <code class="notranslate">first</code> or <code class="notranslate">top</code> keywords, which can be used interchangeably. An optional numeric value can be appended to <code class="notranslate">top</code> or <code class="notranslate">first</code> to specify the maximum result size to be returned. If the number is left out, a result size of 1 is assumed. The following example shows how to limit the query size:</p>
</div>
<div class="exampleblock">
<div class="title">
Example 15. Limiting the result size of a query with
<code class="notranslate">Top</code> and
<code class="notranslate">First</code>
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight notranslate"><code class="language-java" data-lang="java">User findFirstByOrderByLastnameAsc();

User findTopByOrderByAgeDesc();

Page&lt;User&gt; queryFirst10ByLastname(String lastname, Pageable pageable);

Slice&lt;User&gt; findTop3ByLastname(String lastname, Pageable pageable);

List&lt;User&gt; findFirst10ByLastname(String lastname, Sort sort);

List&lt;User&gt; findTop10ByLastname(String lastname, Pageable pageable);</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<p>The limiting expressions also support the <code class="notranslate">Distinct</code> keyword. Also, for the queries limiting the result set to one instance, wrapping the result into with the <code class="notranslate">Optional</code> keyword is supported.</p>
</div>
<div class="paragraph">
<p>If pagination or slicing is applied to a limiting query pagination (and the calculation of the number of pages available), it is applied within the limited result.</p>
</div>
<div class="admonitionblock note">
<table>
<tbody>
<tr>
<td class="icon"> <i class="fa icon-note" title="Note"></i> </td>
<td class="content"> Limiting the results in combination with dynamic sorting by using a <code class="notranslate">Sort</code> parameter lets you express query methods for the 'K' smallest as well as for the 'K' biggest elements. </td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="sect3">
<h4 id="repositories.collections-and-iterables"><a class="anchor" href="#repositories.collections-and-iterables"></a>3.4.6. Repository Methods Returning Collections or Iterables</h4>
<div class="paragraph">
<p>Query methods that return multiple results can use standard Java <code class="notranslate">Iterable</code>, <code class="notranslate">List</code>, <code class="notranslate">Set</code>. Beyond that we support returning Spring Data’s <code class="notranslate">Streamable</code>, a custom extension of <code class="notranslate">Iterable</code>, as well as collection types provided by <a href="javascript:window.open('http://www.vavr.io/');" target="_blank" rel="noopener noreferrer">Vavr <i class="fa fa-external-link"></i></a>.</p>
</div>
<div class="sect4">
<h5 id="repositories.collections-and-iterables.streamable"><a class="anchor" href="#repositories.collections-and-iterables.streamable"></a>Using Streamable as Query Method Return Type</h5>
<div class="paragraph">
<p><code class="notranslate">Streamable</code> can be used as alternative to <code class="notranslate">Iterable</code> or any collection type. It provides convenience methods to access a non-parallel <code class="notranslate">Stream</code> (missing from <code class="notranslate">Iterable</code>), the ability to directly <code class="notranslate">….filter(…)</code> and <code class="notranslate">….map(…)</code> over the elements and concatenate the <code class="notranslate">Streamable</code> to others:</p>
</div>
<div class="exampleblock">
<div class="title">
Example 16. Using Streamable to combine query method results
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight notranslate"><code class="language-java" data-lang="java">interface PersonRepository extends Repository&lt;Person, Long&gt; {
  Streamable&lt;Person&gt; findByFirstnameContaining(String firstname);
  Streamable&lt;Person&gt; findByLastnameContaining(String lastname);
}

Streamable&lt;Person&gt; result = repository.findByFirstnameContaining("av")
  .and(repository.findByLastnameContaining("ea"));</code></pre>
</div>
</div>
</div>
</div>
</div>
<div class="sect4">
<h5 id="repositories.collections-and-iterables.streamable-wrapper"><a class="anchor" href="#repositories.collections-and-iterables.streamable-wrapper"></a>Returning Custom Streamable Wrapper Types</h5>
<div class="paragraph">
<p>Providing dedicated wrapper types for collections is a commonly used pattern to provide API on a query execution result that returns multiple elements. Usually these types are used by invoking a repository method returning a collection-like type and creating an instance of the wrapper type manually. That additional step can be avoided as Spring Data allows to use these wrapper types as query method return types if they meet the following criterias:</p>
</div>
<div class="olist arabic">
<ol class="arabic">
<li> <p>The type implements <code class="notranslate">Streamable</code>.</p> </li>
<li> <p>The type exposes either a constructor or a static factory method named <code class="notranslate">of(…)</code> or <code class="notranslate">valueOf(…)</code> taking <code class="notranslate">Streamable</code> as argument.</p> </li>
</ol>
</div>
<div class="paragraph">
<p>A sample use case looks as follows:</p>
</div>
<div class="exampleblock">
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight notranslate"><code class="language-java" data-lang="java">class Product { <i class="conum" data-value="1"></i><b>(1)</b>
  MonetaryAmount getPrice() { … }
}

@RequiredArgConstructor(staticName = "of")
class Products implements Streamable&lt;Product&gt; { <i class="conum" data-value="2"></i><b>(2)</b>

  private Streamable&lt;Product&gt; streamable;

  public MonetaryAmount getTotal() { <i class="conum" data-value="3"></i><b>(3)</b>
    return streamable.stream() //
      .map(Priced::getPrice)
      .reduce(Money.of(0), MonetaryAmount::add);
  }
}

interface ProductRepository implements Repository&lt;Product, Long&gt; {
  Products findAllByDescriptionContaining(String text); <i class="conum" data-value="4"></i><b>(4)</b>
}</code></pre>
</div>
</div>
<div class="colist arabic">
<table>
<tbody>
<tr>
<td><i class="conum" data-value="1"></i><b class="notranslate">1</b></td>
<td>A <code class="notranslate">Product</code> entity that exposes API to access the product’s price.</td>
</tr>
<tr>
<td><i class="conum" data-value="2"></i><b class="notranslate">2</b></td>
<td>A wrapper type for a <code class="notranslate">Streamable&lt;Product&gt;</code> that can be constructed via <code class="notranslate">Products.of(…)</code> (factory method created via the Lombok annotation).</td>
</tr>
<tr>
<td><i class="conum" data-value="3"></i><b class="notranslate">3</b></td>
<td>The wrapper type exposes additional API calculating new values on the <code class="notranslate">Streamable&lt;Product&gt;</code>.</td>
</tr>
<tr>
<td><i class="conum" data-value="4"></i><b class="notranslate">4</b></td>
<td>That wrapper type can be used as query method return type directly. No need to return <code class="notranslate">Stremable&lt;Product&gt;</code> and manually wrap it in the repository client.</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
<div class="sect4">
<h5 id="repositories.collections-and-iterables.vavr"><a class="anchor" href="#repositories.collections-and-iterables.vavr"></a>Support for Vavr Collections</h5>
<div class="paragraph">
<p><a href="javascript:window.open('http://www.vavr.io/');" target="_blank" rel="noopener noreferrer">Vavr <i class="fa fa-external-link"></i></a> is a library to embrace functional programming concepts in Java. It ships with a custom set of collection types that can be used as query method return types.</p>
</div>
<table class="tableblock frame-all grid-all stretch">
<colgroup>
<col style="width: 33.3333%;">
<col style="width: 33.3333%;">
<col style="width: 33.3334%;">
</colgroup>
<thead>
<tr>
<th class="tableblock halign-left valign-top">Vavr collection type</th>
<th class="tableblock halign-left valign-top">Used Vavr implementation type</th>
<th class="tableblock halign-left valign-top">Valid Java source types</th>
</tr>
</thead>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code class="notranslate">io.vavr.collection.Seq</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code class="notranslate">io.vavr.collection.List</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code class="notranslate">java.util.Iterable</code></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code class="notranslate">io.vavr.collection.Set</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code class="notranslate">io.vavr.collection.LinkedHashSet</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code class="notranslate">java.util.Iterable</code></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code class="notranslate">io.vavr.collection.Map</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code class="notranslate">io.vavr.collection.LinkedHashMap</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code class="notranslate">java.util.Map</code></p></td>
</tr>
</tbody>
</table>
<div class="paragraph">
<p>The types in the first column (or subtypes thereof) can be used as quer method return types and will get the types in the second column used as implementation type depending on the Java type of the actual query result (thrid column). Alternatively, <code class="notranslate">Traversable</code> (Vavr the <code class="notranslate">Iterable</code> equivalent) can be declared and we derive the implementation class from the actual return value, i.e. a <code class="notranslate">java.util.List</code> will be turned into a Vavr <code class="notranslate">List</code>/<code class="notranslate">Seq</code>, a <code class="notranslate">java.util.Set</code> becomes a Vavr <code class="notranslate">LinkedHashSet</code>/<code class="notranslate">Set</code> etc.</p>
</div>
</div>
</div>
<div class="sect3">
<h4 id="repositories.nullability"><a class="anchor" href="#repositories.nullability"></a>3.4.7. Null Handling of Repository Methods</h4>
<div class="paragraph">
<p>As of Spring Data 2.0, repository CRUD methods that return an individual aggregate instance use Java 8’s <code class="notranslate">Optional</code> to indicate the potential absence of a value. Besides that, Spring Data supports returning the following wrapper types on query methods:</p>
</div>
<div class="ulist">
<ul>
<li> <p><code class="notranslate">com.google.common.base.Optional</code></p> </li>
<li> <p><code class="notranslate">scala.Option</code></p> </li>
<li> <p><code class="notranslate">io.vavr.control.Option</code></p> </li>
</ul>
</div>
<div class="paragraph">
<p>Alternatively, query methods can choose not to use a wrapper type at all. The absence of a query result is then indicated by returning <code class="notranslate">null</code>. Repository methods returning collections, collection alternatives, wrappers, and streams are guaranteed never to return <code class="notranslate">null</code> but rather the corresponding empty representation. See “<a href="#repository-query-return-types">Repository query return types</a>” for details.</p>
</div>
<div class="sect4">
<h5 id="repositories.nullability.annotations"><a class="anchor" href="#repositories.nullability.annotations"></a>Nullability Annotations</h5>
<div class="paragraph">
<p>You can express nullability constraints for repository methods by using <a href="javascript:window.open('https://docs.spring.io/spring/docs/5.1.5.RELEASE/spring-framework-reference/core.html#null-safety');" target="_blank" rel="noopener noreferrer">Spring Framework’s nullability annotations <i class="fa fa-external-link"></i></a>. They provide a tooling-friendly approach and opt-in <code class="notranslate">null</code> checks during runtime, as follows:</p>
</div>
<div class="ulist">
<ul>
<li> <p><a href="javascript:window.open('https://docs.spring.io/spring/docs/5.1.5.RELEASE/javadoc-api/org/springframework/lang/NonNullApi.html');" target="_blank" rel="noopener noreferrer"><code class="notranslate">@NonNullApi</code> <i class="fa fa-external-link"></i></a>: Used on the package level to declare that the default behavior for parameters and return values is to not accept or produce <code class="notranslate">null</code> values.</p> </li>
<li> <p><a href="javascript:window.open('https://docs.spring.io/spring/docs/5.1.5.RELEASE/javadoc-api/org/springframework/lang/NonNull.html');" target="_blank" rel="noopener noreferrer"><code class="notranslate">@NonNull</code> <i class="fa fa-external-link"></i></a>: Used on a parameter or return value that must not be <code class="notranslate">null</code> (not needed on a parameter and return value where <code class="notranslate">@NonNullApi</code> applies).</p> </li>
<li> <p><a href="javascript:window.open('https://docs.spring.io/spring/docs/5.1.5.RELEASE/javadoc-api/org/springframework/lang/Nullable.html');" target="_blank" rel="noopener noreferrer"><code class="notranslate">@Nullable</code> <i class="fa fa-external-link"></i></a>: Used on a parameter or return value that can be <code class="notranslate">null</code>.</p> </li>
</ul>
</div>
<div class="paragraph">
<p>Spring annotations are meta-annotated with <a href="javascript:window.open('https://jcp.org/en/jsr/detail?id=305');" target="_blank" rel="noopener noreferrer">JSR 305 <i class="fa fa-external-link"></i></a> annotations (a dormant but widely spread JSR). JSR 305 meta-annotations let tooling vendors such as <a href="javascript:window.open('https://www.jetbrains.com/help/idea/nullable-and-notnull-annotations.html');" target="_blank" rel="noopener noreferrer">IDEA <i class="fa fa-external-link"></i></a>, <a href="javascript:window.open('https://help.eclipse.org/oxygen/index.jsp?topic=/org.eclipse.jdt.doc.user/tasks/task-using_external_null_annotations.htm');" target="_blank" rel="noopener noreferrer">Eclipse <i class="fa fa-external-link"></i></a>, and <a href="javascript:window.open('https://kotlinlang.org/docs/reference/java-interop.html#null-safety-and-platform-types');" target="_blank" rel="noopener noreferrer">Kotlin <i class="fa fa-external-link"></i></a> provide null-safety support in a generic way, without having to hard-code support for Spring annotations. To enable runtime checking of nullability constraints for query methods, you need to activate non-nullability on the package level by using Spring’s <code class="notranslate">@NonNullApi</code> in <code class="notranslate">package-info.java</code>, as shown in the following example:</p>
</div>
<div class="exampleblock">
<div class="title">
Example 17. Declaring Non-nullability in
<code class="notranslate">package-info.java</code>
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight notranslate"><code class="language-java" data-lang="java">@org.springframework.lang.NonNullApi
package com.acme;</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<p>Once non-null defaulting is in place, repository query method invocations get validated at runtime for nullability constraints. If a query execution result violates the defined constraint, an exception is thrown. This happens when the method would return <code class="notranslate">null</code> but is declared as non-nullable (the default with the annotation defined on the package the repository resides in). If you want to opt-in to nullable results again, selectively use <code class="notranslate">@Nullable</code> on individual methods. Using the result wrapper types mentioned at the start of this section continues to work as expected: An empty result is translated into the value that represents absence.</p>
</div>
<div class="paragraph">
<p>The following example shows a number of the techniques just described:</p>
</div>
<div class="exampleblock">
<div class="title">
Example 18. Using different nullability constraints
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight notranslate"><code class="language-java" data-lang="java">package com.acme;                                                       <i class="conum" data-value="1"></i><b>(1)</b>

import org.springframework.lang.Nullable;

interface UserRepository extends Repository&lt;User, Long&gt; {

  User getByEmailAddress(EmailAddress emailAddress);                    <i class="conum" data-value="2"></i><b>(2)</b>

  @Nullable
  User findByEmailAddress(@Nullable EmailAddress emailAdress);          <i class="conum" data-value="3"></i><b>(3)</b>

  Optional&lt;User&gt; findOptionalByEmailAddress(EmailAddress emailAddress); <i class="conum" data-value="4"></i><b>(4)</b>
}</code></pre>
</div>
</div>
<div class="colist arabic">
<table>
<tbody>
<tr>
<td><i class="conum" data-value="1"></i><b class="notranslate">1</b></td>
<td>The repository resides in a package (or sub-package) for which we have defined non-null behavior.</td>
</tr>
<tr>
<td><i class="conum" data-value="2"></i><b class="notranslate">2</b></td>
<td>Throws an <code class="notranslate">EmptyResultDataAccessException</code> when the query executed does not produce a result. Throws an <code class="notranslate">IllegalArgumentException</code> when the <code class="notranslate">emailAddress</code> handed to the method is <code class="notranslate">null</code>.</td>
</tr>
<tr>
<td><i class="conum" data-value="3"></i><b class="notranslate">3</b></td>
<td>Returns <code class="notranslate">null</code> when the query executed does not produce a result. Also accepts <code class="notranslate">null</code> as the value for <code class="notranslate">emailAddress</code>.</td>
</tr>
<tr>
<td><i class="conum" data-value="4"></i><b class="notranslate">4</b></td>
<td>Returns <code class="notranslate">Optional.empty()</code> when the query executed does not produce a result. Throws an <code class="notranslate">IllegalArgumentException</code> when the <code class="notranslate">emailAddress</code> handed to the method is <code class="notranslate">null</code>.</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
<div class="sect4">
<h5 id="repositories.nullability.kotlin"><a class="anchor" href="#repositories.nullability.kotlin"></a>Nullability in Kotlin-based Repositories</h5>
<div class="paragraph">
<p>Kotlin has the definition of <a href="javascript:window.open('https://kotlinlang.org/docs/reference/null-safety.html');" target="_blank" rel="noopener noreferrer">nullability constraints <i class="fa fa-external-link"></i></a> baked into the language. Kotlin code compiles to bytecode, which does not express nullability constraints through method signatures but rather through compiled-in metadata. Make sure to include the <code class="notranslate">kotlin-reflect</code> JAR in your project to enable introspection of Kotlin’s nullability constraints. Spring Data repositories use the language mechanism to define those constraints to apply the same runtime checks, as follows:</p>
</div>
<div class="exampleblock">
<div class="title">
Example 19. Using nullability constraints on Kotlin repositories
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight notranslate"><code class="language-kotlin" data-lang="kotlin">interface UserRepository : Repository&lt;User, String&gt; {

  fun findByUsername(username: String): User     <i class="conum" data-value="1"></i><b>(1)</b>

  fun findByFirstname(firstname: String?): User? <i class="conum" data-value="2"></i><b>(2)</b>
}</code></pre>
</div>
</div>
<div class="colist arabic">
<table>
<tbody>
<tr>
<td><i class="conum" data-value="1"></i><b class="notranslate">1</b></td>
<td>The method defines both the parameter and the result as non-nullable (the Kotlin default). The Kotlin compiler rejects method invocations that pass <code class="notranslate">null</code> to the method. If the query execution yields an empty result, an <code class="notranslate">EmptyResultDataAccessException</code> is thrown.</td>
</tr>
<tr>
<td><i class="conum" data-value="2"></i><b class="notranslate">2</b></td>
<td>This method accepts <code class="notranslate">null</code> for the <code class="notranslate">firstname</code> parameter and returns <code class="notranslate">null</code> if the query execution does not produce a result.</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
<div class="sect3">
<h4 id="repositories.query-streaming"><a class="anchor" href="#repositories.query-streaming"></a>3.4.8. Streaming query results</h4>
<div class="paragraph">
<p>The results of query methods can be processed incrementally by using a Java 8 <code class="notranslate">Stream&lt;T&gt;</code> as return type. Instead of wrapping the query results in a <code class="notranslate">Stream</code> data store-specific methods are used to perform the streaming, as shown in the following example:</p>
</div>
<div class="exampleblock">
<div class="title">
Example 20. Stream the result of a query with Java 8
<code class="notranslate">Stream&lt;T&gt;</code>
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight notranslate"><code class="language-java" data-lang="java">@Query("select u from User u")
Stream&lt;User&gt; findAllByCustomQueryAndStream();

Stream&lt;User&gt; readAllByFirstnameNotNull();

@Query("select u from User u")
Stream&lt;User&gt; streamAllPaged(Pageable pageable);</code></pre>
</div>
</div>
</div>
</div>
<div class="admonitionblock note">
<table>
<tbody>
<tr>
<td class="icon"> <i class="fa icon-note" title="Note"></i> </td>
<td class="content"> A <code class="notranslate">Stream</code> potentially wraps underlying data store-specific resources and must, therefore, be closed after usage. You can either manually close the <code class="notranslate">Stream</code> by using the <code class="notranslate">close()</code> method or by using a Java 7 <code class="notranslate">try-with-resources</code> block, as shown in the following example: </td>
</tr>
</tbody>
</table>
</div>
<div class="exampleblock">
<div class="title">
Example 21. Working with a
<code class="notranslate">Stream&lt;T&gt;</code> result in a try-with-resources block
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight notranslate"><code class="language-java" data-lang="java">try (Stream&lt;User&gt; stream = repository.findAllByCustomQueryAndStream()) {
  stream.forEach(…);
}</code></pre>
</div>
</div>
</div>
</div>
<div class="admonitionblock note">
<table>
<tbody>
<tr>
<td class="icon"> <i class="fa icon-note" title="Note"></i> </td>
<td class="content"> Not all Spring Data modules currently support <code class="notranslate">Stream&lt;T&gt;</code> as a return type. </td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="sect3">
<h4 id="repositories.query-async"><a class="anchor" href="#repositories.query-async"></a>3.4.9. Async query results</h4>
<div class="paragraph">
<p>Repository queries can be run asynchronously by using <a href="javascript:window.open('https://docs.spring.io/spring/docs/5.1.5.RELEASE/spring-framework-reference/integration.html#scheduling');" target="_blank" rel="noopener noreferrer">Spring’s asynchronous method execution capability <i class="fa fa-external-link"></i></a>. This means the method returns immediately upon invocation while the actual query execution occurs in a task that has been submitted to a Spring <code class="notranslate">TaskExecutor</code>. Asynchronous query execution is different from reactive query execution and should not be mixed. Refer to store-specific documentation for more details on reactive support. The following example shows a number of asynchronous queries:</p>
</div>
<div class="exampleblock">
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight notranslate"><code class="language-java" data-lang="java">@Async
Future&lt;User&gt; findByFirstname(String firstname);               <i class="conum" data-value="1"></i><b>(1)</b>

@Async
CompletableFuture&lt;User&gt; findOneByFirstname(String firstname); <i class="conum" data-value="2"></i><b>(2)</b>

@Async
ListenableFuture&lt;User&gt; findOneByLastname(String lastname);    <i class="conum" data-value="3"></i><b>(3)</b></code></pre>
</div>
</div>
<div class="colist arabic">
<table>
<tbody>
<tr>
<td><i class="conum" data-value="1"></i><b class="notranslate">1</b></td>
<td>Use <code class="notranslate">java.util.concurrent.Future</code> as the return type.</td>
</tr>
<tr>
<td><i class="conum" data-value="2"></i><b class="notranslate">2</b></td>
<td>Use a Java 8 <code class="notranslate">java.util.concurrent.CompletableFuture</code> as the return type.</td>
</tr>
<tr>
<td><i class="conum" data-value="3"></i><b class="notranslate">3</b></td>
<td>Use a <code class="notranslate">org.springframework.util.concurrent.ListenableFuture</code> as the return type.</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
<div class="sect2">
<h3 id="repositories.create-instances"><a class="anchor" href="#repositories.create-instances"></a>3.5. Creating Repository Instances</h3>
<div class="paragraph">
<p>In this section, you create instances and bean definitions for the defined repository interfaces. One way to do so is by using the Spring namespace that is shipped with each Spring Data module that supports the repository mechanism, although we generally recommend using Java configuration.</p>
</div>
<div class="sect3">
<h4 id="repositories.create-instances.spring"><a class="anchor" href="#repositories.create-instances.spring"></a>3.5.1. XML configuration</h4>
<div class="paragraph">
<p>Each Spring Data module includes a <code class="notranslate">repositories</code> element that lets you define a base package that Spring scans for you, as shown in the following example:</p>
</div>
<div class="exampleblock">
<div class="title">
Example 22. Enabling Spring Data repositories via XML
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight notranslate"><code class="language-xml" data-lang="xml">&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;beans:beans xmlns:beans="http://www.springframework.org/schema/beans"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns="http://www.springframework.org/schema/data/jpa"
  xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/data/jpa
    http://www.springframework.org/schema/data/jpa/spring-jpa.xsd"&gt;

  &lt;repositories base-package="com.acme.repositories" /&gt;

&lt;/beans:beans&gt;</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<p>In the preceding example, Spring is instructed to scan <code class="notranslate">com.acme.repositories</code> and all its sub-packages for interfaces extending <code class="notranslate">Repository</code> or one of its sub-interfaces. For each interface found, the infrastructure registers the persistence technology-specific <code class="notranslate">FactoryBean</code> to create the appropriate proxies that handle invocations of the query methods. Each bean is registered under a bean name that is derived from the interface name, so an interface of <code class="notranslate">UserRepository</code> would be registered under <code class="notranslate">userRepository</code>. The <code class="notranslate">base-package</code> attribute allows wildcards so that you can define a pattern of scanned packages.</p>
</div>
<div class="sect4">
<h5 id="_using_filters"><a class="anchor" href="#_using_filters"></a>Using filters</h5>
<div class="paragraph">
<p>By default, the infrastructure picks up every interface extending the persistence technology-specific <code class="notranslate">Repository</code> sub-interface located under the configured base package and creates a bean instance for it. However, you might want more fine-grained control over which interfaces have bean instances created for them. To do so, use <code class="notranslate">&lt;include-filter /&gt;</code> and <code class="notranslate">&lt;exclude-filter /&gt;</code> elements inside the <code class="notranslate">&lt;repositories /&gt;</code> element. The semantics are exactly equivalent to the elements in Spring’s context namespace. For details, see the <a href="javascript:window.open('https://docs.spring.io/spring/docs/5.1.5.RELEASE/spring-framework-reference/core.html#beans-scanning-filters');" target="_blank" rel="noopener noreferrer">Spring reference documentation <i class="fa fa-external-link"></i></a> for these elements.</p>
</div>
<div class="paragraph">
<p>For example, to exclude certain interfaces from instantiation as repository beans, you could use the following configuration:</p>
</div>
<div class="exampleblock">
<div class="title">
Example 23. Using exclude-filter element
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight notranslate"><code class="language-xml" data-lang="xml">&lt;repositories base-package="com.acme.repositories"&gt;
  &lt;context:exclude-filter type="regex" expression=".*SomeRepository" /&gt;
&lt;/repositories&gt;</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<p>The preceding example excludes all interfaces ending in <code class="notranslate">SomeRepository</code> from being instantiated.</p>
</div>
</div>
</div>
<div class="sect3">
<h4 id="repositories.create-instances.java-config"><a class="anchor" href="#repositories.create-instances.java-config"></a>3.5.2. JavaConfig</h4>
<div class="paragraph">
<p>The repository infrastructure can also be triggered by using a store-specific <code class="notranslate">@Enable${store}Repositories</code> annotation on a JavaConfig class. For an introduction into Java-based configuration of the Spring container, see <a href="javascript:window.open('https://docs.spring.io/spring/docs/5.1.5.RELEASE/spring-framework-reference/core.html#beans-java');" target="_blank" rel="noopener noreferrer">JavaConfig in the Spring reference documentation <i class="fa fa-external-link"></i></a>.</p>
</div>
<div class="paragraph">
<p>A sample configuration to enable Spring Data repositories resembles the following:</p>
</div>
<div class="exampleblock">
<div class="title">
Example 24. Sample annotation based repository configuration
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight notranslate"><code class="language-java" data-lang="java">@Configuration
@EnableJpaRepositories("com.acme.repositories")
class ApplicationConfiguration {

  @Bean
  EntityManagerFactory entityManagerFactory() {
    // …
  }
}</code></pre>
</div>
</div>
</div>
</div>
<div class="admonitionblock note">
<table>
<tbody>
<tr>
<td class="icon"> <i class="fa icon-note" title="Note"></i> </td>
<td class="content"> The preceding example uses the JPA-specific annotation, which you would change according to the store module you actually use. The same applies to the definition of the <code class="notranslate">EntityManagerFactory</code> bean. See the sections covering the store-specific configuration. </td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="sect3">
<h4 id="repositories.create-instances.standalone"><a class="anchor" href="#repositories.create-instances.standalone"></a>3.5.3. Standalone usage</h4>
<div class="paragraph">
<p>You can also use the repository infrastructure outside of a Spring container — for example, in CDI environments. You still need some Spring libraries in your classpath, but, generally, you can set up repositories programmatically as well. The Spring Data modules that provide repository support ship a persistence technology-specific <code class="notranslate">RepositoryFactory</code> that you can use as follows:</p>
</div>
<div class="exampleblock">
<div class="title">
Example 25. Standalone usage of repository factory
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight notranslate"><code class="language-java" data-lang="java">RepositoryFactorySupport factory = … // Instantiate factory here
UserRepository repository = factory.getRepository(UserRepository.class);</code></pre>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="sect2">
<h3 id="repositories.custom-implementations"><a class="anchor" href="#repositories.custom-implementations"></a>3.6. Custom Implementations for Spring Data Repositories</h3>
<div class="paragraph">
<p>This section covers repository customization and how fragments form a composite repository.</p>
</div>
<div class="paragraph">
<p>When a query method requires a different behavior or cannot be implemented by query derivation, then it is necessary to provide a custom implementation. Spring Data repositories let you provide custom repository code and integrate it with generic CRUD abstraction and query method functionality.</p>
</div>
<div class="sect3">
<h4 id="repositories.single-repository-behavior"><a class="anchor" href="#repositories.single-repository-behavior"></a>3.6.1. Customizing Individual Repositories</h4>
<div class="paragraph">
<p>To enrich a repository with custom functionality, you must first define a fragment interface and an implementation for the custom functionality, as shown in the following example:</p>
</div>
<div class="exampleblock">
<div class="title">
Example 26. Interface for custom repository functionality
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight notranslate"><code class="language-java" data-lang="java">interface CustomizedUserRepository {
  void someCustomMethod(User user);
}</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<p>Then you can let your repository interface additionally extend from the fragment interface, as shown in the following example:</p>
</div>
<div class="exampleblock">
<div class="title">
Example 27. Implementation of custom repository functionality
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight notranslate"><code class="language-java" data-lang="java">class CustomizedUserRepositoryImpl implements CustomizedUserRepository {

  public void someCustomMethod(User user) {
    // Your custom implementation
  }
}</code></pre>
</div>
</div>
</div>
</div>
<div class="admonitionblock note">
<table>
<tbody>
<tr>
<td class="icon"> <i class="fa icon-note" title="Note"></i> </td>
<td class="content"> The most important part of the class name that corresponds to the fragment interface is the <code class="notranslate">Impl</code> postfix. </td>
</tr>
</tbody>
</table>
</div>
<div class="paragraph">
<p>The implementation itself does not depend on Spring Data and can be a regular Spring bean. Consequently, you can use standard dependency injection behavior to inject references to other beans (such as a <code class="notranslate">JdbcTemplate</code>), take part in aspects, and so on.</p>
</div>
<div class="paragraph">
<p>You can let your repository interface extend the fragment interface, as shown in the following example:</p>
</div>
<div class="exampleblock">
<div class="title">
Example 28. Changes to your repository interface
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight notranslate"><code class="language-java" data-lang="java">interface UserRepository extends CrudRepository&lt;User, Long&gt;, CustomizedUserRepository {

  // Declare query methods here
}</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<p>Extending the fragment interface with your repository interface combines the CRUD and custom functionality and makes it available to clients.</p>
</div>
<div class="paragraph">
<p>Spring Data repositories are implemented by using fragments that form a repository composition. Fragments are the base repository, functional aspects (such as <a href="#core.extensions.querydsl">QueryDsl</a>), and custom interfaces along with their implementation. Each time you add an interface to your repository interface, you enhance the composition by adding a fragment. The base repository and repository aspect implementations are provided by each Spring Data module.</p>
</div>
<div class="paragraph">
<p>The following example shows custom interfaces and their implementations:</p>
</div>
<div class="exampleblock">
<div class="title">
Example 29. Fragments with their implementations
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight notranslate"><code class="language-java" data-lang="java">interface HumanRepository {
  void someHumanMethod(User user);
}

class HumanRepositoryImpl implements HumanRepository {

  public void someHumanMethod(User user) {
    // Your custom implementation
  }
}

interface ContactRepository {

  void someContactMethod(User user);

  User anotherContactMethod(User user);
}

class ContactRepositoryImpl implements ContactRepository {

  public void someContactMethod(User user) {
    // Your custom implementation
  }

  public User anotherContactMethod(User user) {
    // Your custom implementation
  }
}</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<p>The following example shows the interface for a custom repository that extends <code class="notranslate">CrudRepository</code>:</p>
</div>
<div class="exampleblock">
<div class="title">
Example 30. Changes to your repository interface
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight notranslate"><code class="language-java" data-lang="java">interface UserRepository extends CrudRepository&lt;User, Long&gt;, HumanRepository, ContactRepository {

  // Declare query methods here
}</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<p>Repositories may be composed of multiple custom implementations that are imported in the order of their declaration. Custom implementations have a higher priority than the base implementation and repository aspects. This ordering lets you override base repository and aspect methods and resolves ambiguity if two fragments contribute the same method signature. Repository fragments are not limited to use in a single repository interface. Multiple repositories may use a fragment interface, letting you reuse customizations across different repositories.</p>
</div>
<div class="paragraph">
<p>The following example shows a repository fragment and its implementation:</p>
</div>
<div class="exampleblock">
<div class="title">
Example 31. Fragments overriding
<code class="notranslate">save(…)</code>
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight notranslate"><code class="language-java" data-lang="java">interface CustomizedSave&lt;T&gt; {
  &lt;S extends T&gt; S save(S entity);
}

class CustomizedSaveImpl&lt;T&gt; implements CustomizedSave&lt;T&gt; {

  public &lt;S extends T&gt; S save(S entity) {
    // Your custom implementation
  }
}</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<p>The following example shows a repository that uses the preceding repository fragment:</p>
</div>
<div class="exampleblock">
<div class="title">
Example 32. Customized repository interfaces
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight notranslate"><code class="language-java" data-lang="java">interface UserRepository extends CrudRepository&lt;User, Long&gt;, CustomizedSave&lt;User&gt; {
}

interface PersonRepository extends CrudRepository&lt;Person, Long&gt;, CustomizedSave&lt;Person&gt; {
}</code></pre>
</div>
</div>
</div>
</div>
<div class="sect4">
<h5 id="_configuration"><a class="anchor" href="#_configuration"></a>Configuration</h5>
<div class="paragraph">
<p>If you use namespace configuration, the repository infrastructure tries to autodetect custom implementation fragments by scanning for classes below the package in which it found a repository. These classes need to follow the naming convention of appending the namespace element’s <code class="notranslate">repository-impl-postfix</code> attribute to the fragment interface name. This postfix defaults to <code class="notranslate">Impl</code>. The following example shows a repository that uses the default postfix and a repository that sets a custom value for the postfix:</p>
</div>
<div class="exampleblock">
<div class="title">
Example 33. Configuration example
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight notranslate"><code class="language-xml" data-lang="xml">&lt;repositories base-package="com.acme.repository" /&gt;

&lt;repositories base-package="com.acme.repository" repository-impl-postfix="MyPostfix" /&gt;</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<p>The first configuration in the preceding example tries to look up a class called <code class="notranslate">com.acme.repository.CustomizedUserRepositoryImpl</code> to act as a custom repository implementation. The second example tries to lookup <code class="notranslate">com.acme.repository.CustomizedUserRepositoryMyPostfix</code>.</p>
</div>
<div class="sect5">
<h6 id="repositories.single-repository-behaviour.ambiguity"><a class="anchor" href="#repositories.single-repository-behaviour.ambiguity"></a>Resolution of Ambiguity</h6>
<div class="paragraph">
<p>If multiple implementations with matching class names are found in different packages, Spring Data uses the bean names to identify which one to use.</p>
</div>
<div class="paragraph">
<p>Given the following two custom implementations for the <code class="notranslate">CustomizedUserRepository</code> shown earlier, the first implementation is used. Its bean name is <code class="notranslate">customizedUserRepositoryImpl</code>, which matches that of the fragment interface (<code class="notranslate">CustomizedUserRepository</code>) plus the postfix <code class="notranslate">Impl</code>.</p>
</div>
<div class="exampleblock">
<div class="title">
Example 34. Resolution of amibiguous implementations
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight notranslate"><code class="language-java" data-lang="java">package com.acme.impl.one;

class CustomizedUserRepositoryImpl implements CustomizedUserRepository {

  // Your custom implementation
}</code></pre>
</div>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight notranslate"><code class="language-java" data-lang="java">package com.acme.impl.two;

@Component("specialCustomImpl")
class CustomizedUserRepositoryImpl implements CustomizedUserRepository {

  // Your custom implementation
}</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<p>If you annotate the <code class="notranslate">UserRepository</code> interface with <code class="notranslate">@Component("specialCustom")</code>, the bean name plus <code class="notranslate">Impl</code> then matches the one defined for the repository implementation in <code class="notranslate">com.acme.impl.two</code>, and it is used instead of the first one.</p>
</div>
</div>
<div class="sect5">
<h6 id="repositories.manual-wiring"><a class="anchor" href="#repositories.manual-wiring"></a>Manual Wiring</h6>
<div class="paragraph">
<p>If your custom implementation uses annotation-based configuration and autowiring only, the preceding approach shown works well, because it is treated as any other Spring bean. If your implementation fragment bean needs special wiring, you can declare the bean and name it according to the conventions described in the <a href="#repositories.single-repository-behaviour.ambiguity">preceding section</a>. The infrastructure then refers to the manually defined bean definition by name instead of creating one itself. The following example shows how to manually wire a custom implementation:</p>
</div>
<div class="exampleblock">
<div class="title">
Example 35. Manual wiring of custom implementations
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight notranslate"><code class="language-xml" data-lang="xml">&lt;repositories base-package="com.acme.repository" /&gt;

&lt;beans:bean id="userRepositoryImpl" class="…"&gt;
  &lt;!-- further configuration --&gt;
&lt;/beans:bean&gt;</code></pre>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="sect3">
<h4 id="repositories.customize-base-repository"><a class="anchor" href="#repositories.customize-base-repository"></a>3.6.2. Customize the Base Repository</h4>
<div class="paragraph">
<p>The approach described in the <a href="#repositories.manual-wiring">preceding section</a> requires customization of each repository interfaces when you want to customize the base repository behavior so that all repositories are affected. To instead change behavior for all repositories, you can create an implementation that extends the persistence technology-specific repository base class. This class then acts as a custom base class for the repository proxies, as shown in the following example:</p>
</div>
<div class="exampleblock">
<div class="title">
Example 36. Custom repository base class
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight notranslate"><code class="language-java" data-lang="java">class MyRepositoryImpl&lt;T, ID&gt;
  extends SimpleJpaRepository&lt;T, ID&gt; {

  private final EntityManager entityManager;

  MyRepositoryImpl(JpaEntityInformation entityInformation,
                          EntityManager entityManager) {
    super(entityInformation, entityManager);

    // Keep the EntityManager around to used from the newly introduced methods.
    this.entityManager = entityManager;
  }

  @Transactional
  public &lt;S extends T&gt; S save(S entity) {
    // implementation goes here
  }
}</code></pre>
</div>
</div>
</div>
</div>
<div class="admonitionblock caution">
<table>
<tbody>
<tr>
<td class="icon"> <i class="fa icon-caution" title="Caution"></i> </td>
<td class="content"> The class needs to have a constructor of the super class which the store-specific repository factory implementation uses. If the repository base class has multiple constructors, override the one taking an <code class="notranslate">EntityInformation</code> plus a store specific infrastructure object (such as an <code class="notranslate">EntityManager</code> or a template class). </td>
</tr>
</tbody>
</table>
</div>
<div class="paragraph">
<p>The final step is to make the Spring Data infrastructure aware of the customized repository base class. In Java configuration, you can do so by using the <code class="notranslate">repositoryBaseClass</code> attribute of the <code class="notranslate">@Enable${store}Repositories</code> annotation, as shown in the following example:</p>
</div>
<div class="exampleblock">
<div class="title">
Example 37. Configuring a custom repository base class using JavaConfig
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight notranslate"><code class="language-java" data-lang="java">@Configuration
@EnableJpaRepositories(repositoryBaseClass = MyRepositoryImpl.class)
class ApplicationConfiguration { … }</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<p>A corresponding attribute is available in the XML namespace, as shown in the following example:</p>
</div>
<div class="exampleblock">
<div class="title">
Example 38. Configuring a custom repository base class using XML
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight notranslate"><code class="language-xml" data-lang="xml">&lt;repositories base-package="com.acme.repository"
     base-class="….MyRepositoryImpl" /&gt;</code></pre>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="sect2">
<h3 id="core.domain-events"><a class="anchor" href="#core.domain-events"></a>3.7. Publishing Events from Aggregate Roots</h3>
<div class="paragraph">
<p>Entities managed by repositories are aggregate roots. In a Domain-Driven Design application, these aggregate roots usually publish domain events. Spring Data provides an annotation called <code class="notranslate">@DomainEvents</code> that you can use on a method of your aggregate root to make that publication as easy as possible, as shown in the following example:</p>
</div>
<div class="exampleblock">
<div class="title">
Example 39. Exposing domain events from an aggregate root
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight notranslate"><code class="language-java" data-lang="java">class AnAggregateRoot {

    @DomainEvents <i class="conum" data-value="1"></i><b>(1)</b>
    Collection&lt;Object&gt; domainEvents() {
        // … return events you want to get published here
    }

    @AfterDomainEventPublication <i class="conum" data-value="2"></i><b>(2)</b>
    void callbackMethod() {
       // … potentially clean up domain events list
    }
}</code></pre>
</div>
</div>
<div class="colist arabic">
<table>
<tbody>
<tr>
<td><i class="conum" data-value="1"></i><b class="notranslate">1</b></td>
<td>The method using <code class="notranslate">@DomainEvents</code> can return either a single event instance or a collection of events. It must not take any arguments.</td>
</tr>
<tr>
<td><i class="conum" data-value="2"></i><b class="notranslate">2</b></td>
<td>After all events have been published, we have a method annotated with <code class="notranslate">@AfterDomainEventPublication</code>. It can be used to potentially clean the list of events to be published (among other uses).</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<div class="paragraph">
<p>The methods are called every time one of a Spring Data repository’s <code class="notranslate">save(…)</code> methods is called.</p>
</div>
</div>
<div class="sect2">
<h3 id="core.extensions"><a class="anchor" href="#core.extensions"></a>3.8. Spring Data Extensions</h3>
<div class="paragraph">
<p>This section documents a set of Spring Data extensions that enable Spring Data usage in a variety of contexts. Currently, most of the integration is targeted towards Spring MVC.</p>
</div>
<div class="sect3">
<h4 id="core.extensions.querydsl"><a class="anchor" href="#core.extensions.querydsl"></a>3.8.1. Querydsl Extension</h4>
<div class="paragraph">
<p><a href="javascript:window.open('http://www.querydsl.com/');" target="_blank" rel="noopener noreferrer">Querydsl <i class="fa fa-external-link"></i></a> is a framework that enables the construction of statically typed SQL-like queries through its fluent API.</p>
</div>
<div class="paragraph">
<p>Several Spring Data modules offer integration with Querydsl through <code class="notranslate">QuerydslPredicateExecutor</code>, as shown in the following example:</p>
</div>
<div class="exampleblock">
<div class="title">
Example 40. QuerydslPredicateExecutor interface
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight notranslate"><code class="language-java" data-lang="java">public interface QuerydslPredicateExecutor&lt;T&gt; {

  Optional&lt;T&gt; findById(Predicate predicate);  <i class="conum" data-value="1"></i><b>(1)</b>

  Iterable&lt;T&gt; findAll(Predicate predicate);   <i class="conum" data-value="2"></i><b>(2)</b>

  long count(Predicate predicate);            <i class="conum" data-value="3"></i><b>(3)</b>

  boolean exists(Predicate predicate);        <i class="conum" data-value="4"></i><b>(4)</b>

  // … more functionality omitted.
}</code></pre>
</div>
</div>
<div class="colist arabic">
<table>
<tbody>
<tr>
<td><i class="conum" data-value="1"></i><b class="notranslate">1</b></td>
<td>Finds and returns a single entity matching the <code class="notranslate">Predicate</code>.</td>
</tr>
<tr>
<td><i class="conum" data-value="2"></i><b class="notranslate">2</b></td>
<td>Finds and returns all entities matching the <code class="notranslate">Predicate</code>.</td>
</tr>
<tr>
<td><i class="conum" data-value="3"></i><b class="notranslate">3</b></td>
<td>Returns the number of entities matching the <code class="notranslate">Predicate</code>.</td>
</tr>
<tr>
<td><i class="conum" data-value="4"></i><b class="notranslate">4</b></td>
<td>Returns whether an entity that matches the <code class="notranslate">Predicate</code> exists.</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<div class="paragraph">
<p>To make use of Querydsl support, extend <code class="notranslate">QuerydslPredicateExecutor</code> on your repository interface, as shown in the following example</p>
</div>
<div class="exampleblock">
<div class="title">
Example 41. Querydsl integration on repositories
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight notranslate"><code class="language-java" data-lang="java">interface UserRepository extends CrudRepository&lt;User, Long&gt;, QuerydslPredicateExecutor&lt;User&gt; {
}</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<p>The preceding example lets you write typesafe queries using Querydsl <code class="notranslate">Predicate</code> instances, as shown in the following example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight notranslate"><code class="language-java" data-lang="java">Predicate predicate = user.firstname.equalsIgnoreCase("dave")
	.and(user.lastname.startsWithIgnoreCase("mathews"));

userRepository.findAll(predicate);</code></pre>
</div>
</div>
</div>
<div class="sect3">
<h4 id="core.web"><a class="anchor" href="#core.web"></a>3.8.2. Web support</h4>
<div class="admonitionblock note">
<table>
<tbody>
<tr>
<td class="icon"> <i class="fa icon-note" title="Note"></i> </td>
<td class="content"> This section contains the documentation for the Spring Data web support as it is implemented in the current (and later) versions of Spring Data Commons. As the newly introduced support changes many things, we kept the documentation of the former behavior in <a href="#web.legacy">[web.legacy]</a>. </td>
</tr>
</tbody>
</table>
</div>
<div class="paragraph">
<p>Spring Data modules that support the repository programming model ship with a variety of web support. The web related components require Spring MVC JARs to be on the classpath. Some of them even provide integration with <a href="javascript:window.open('https://github.com/SpringSource/spring-hateoas');" target="_blank" rel="noopener noreferrer">Spring HATEOAS <i class="fa fa-external-link"></i></a>. In general, the integration support is enabled by using the <code class="notranslate">@EnableSpringDataWebSupport</code> annotation in your JavaConfig configuration class, as shown in the following example:</p>
</div>
<div class="exampleblock">
<div class="title">
Example 42. Enabling Spring Data web support
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight notranslate"><code class="language-java" data-lang="java">@Configuration
@EnableWebMvc
@EnableSpringDataWebSupport
class WebConfiguration {}</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<p>The <code class="notranslate">@EnableSpringDataWebSupport</code> annotation registers a few components we will discuss in a bit. It will also detect Spring HATEOAS on the classpath and register integration components for it as well if present.</p>
</div>
<div class="paragraph">
<p>Alternatively, if you use XML configuration, register either <code class="notranslate">SpringDataWebConfiguration</code> or <code class="notranslate">HateoasAwareSpringDataWebConfiguration</code> as Spring beans, as shown in the following example (for <code class="notranslate">SpringDataWebConfiguration</code>):</p>
</div>
<div class="exampleblock">
<div class="title">
Example 43. Enabling Spring Data web support in XML
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight notranslate"><code class="language-xml" data-lang="xml">&lt;bean class="org.springframework.data.web.config.SpringDataWebConfiguration" /&gt;

&lt;!-- If you use Spring HATEOAS, register this one *instead* of the former --&gt;
&lt;bean class="org.springframework.data.web.config.HateoasAwareSpringDataWebConfiguration" /&gt;</code></pre>
</div>
</div>
</div>
</div>
<div class="sect4">
<h5 id="core.web.basic"><a class="anchor" href="#core.web.basic"></a>Basic Web Support</h5>
<div class="paragraph">
<p>The configuration shown in the <a href="#core.web">previous section</a> registers a few basic components:</p>
</div>
<div class="ulist">
<ul>
<li> <p>A <a href="#core.web.basic.domain-class-converter"><code class="notranslate">DomainClassConverter</code></a> to let Spring MVC resolve instances of repository-managed domain classes from request parameters or path variables.</p> </li>
<li> <p><a href="#core.web.basic.paging-and-sorting"><code class="notranslate">HandlerMethodArgumentResolver</code></a> implementations to let Spring MVC resolve <code class="notranslate">Pageable</code> and <code class="notranslate">Sort</code> instances from request parameters.</p> </li>
</ul>
</div>
<div class="sect5">
<h6 id="core.web.basic.domain-class-converter"><a class="anchor" href="#core.web.basic.domain-class-converter"></a><code class="notranslate">DomainClassConverter</code></h6>
<div class="paragraph">
<p>The <code class="notranslate">DomainClassConverter</code> lets you use domain types in your Spring MVC controller method signatures directly, so that you need not manually lookup the instances through the repository, as shown in the following example:</p>
</div>
<div class="exampleblock">
<div class="title">
Example 44. A Spring MVC controller using domain types in method signatures
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight notranslate"><code class="language-java" data-lang="java">@Controller
@RequestMapping("/users")
class UserController {

  @RequestMapping("/{id}")
  String showUserForm(@PathVariable("id") User user, Model model) {

    model.addAttribute("user", user);
    return "userForm";
  }
}</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<p>As you can see, the method receives a <code class="notranslate">User</code> instance directly, and no further lookup is necessary. The instance can be resolved by letting Spring MVC convert the path variable into the <code class="notranslate">id</code> type of the domain class first and eventually access the instance through calling <code class="notranslate">findById(…)</code> on the repository instance registered for the domain type.</p>
</div>
<div class="admonitionblock note">
<table>
<tbody>
<tr>
<td class="icon"> <i class="fa icon-note" title="Note"></i> </td>
<td class="content"> Currently, the repository has to implement <code class="notranslate">CrudRepository</code> to be eligible to be discovered for conversion. </td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="sect5">
<h6 id="core.web.basic.paging-and-sorting"><a class="anchor" href="#core.web.basic.paging-and-sorting"></a>HandlerMethodArgumentResolvers for Pageable and Sort</h6>
<div class="paragraph">
<p>The configuration snippet shown in the <a href="#core.web.basic.domain-class-converter">previous section</a> also registers a <code class="notranslate">PageableHandlerMethodArgumentResolver</code> as well as an instance of <code class="notranslate">SortHandlerMethodArgumentResolver</code>. The registration enables <code class="notranslate">Pageable</code> and <code class="notranslate">Sort</code> as valid controller method arguments, as shown in the following example:</p>
</div>
<div class="exampleblock">
<div class="title">
Example 45. Using Pageable as controller method argument
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight notranslate"><code class="language-java" data-lang="java">@Controller
@RequestMapping("/users")
class UserController {

  private final UserRepository repository;

  UserController(UserRepository repository) {
    this.repository = repository;
  }

  @RequestMapping
  String showUsers(Model model, Pageable pageable) {

    model.addAttribute("users", repository.findAll(pageable));
    return "users";
  }
}</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<p>The preceding method signature causes Spring MVC try to derive a <code class="notranslate">Pageable</code> instance from the request parameters by using the following default configuration:</p>
</div>
<table class="tableblock frame-all grid-all fit-content">
<caption class="title">
Table 1. Request parameters evaluated for
<code class="notranslate">Pageable</code> instances
</caption>
<colgroup>
<col>
<col>
</colgroup>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code class="notranslate">page</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Page you want to retrieve. 0-indexed and defaults to 0.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code class="notranslate">size</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Size of the page you want to retrieve. Defaults to 20.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code class="notranslate">sort</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Properties that should be sorted by in the format <code class="notranslate">property,property(,ASC|DESC)</code>. Default sort direction is ascending. Use multiple <code class="notranslate">sort</code> parameters if you want to switch directions — for example, <code class="notranslate">?sort=firstname&amp;sort=lastname,asc</code>.</p></td>
</tr>
</tbody>
</table>
<div class="paragraph">
<p>To customize this behavior, register a bean implementing the <code class="notranslate">PageableHandlerMethodArgumentResolverCustomizer</code> interface or the <code class="notranslate">SortHandlerMethodArgumentResolverCustomizer</code> interface, respectively. Its <code class="notranslate">customize()</code> method gets called, letting you change settings, as shown in the following example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight notranslate"><code class="language-java" data-lang="java">@Bean SortHandlerMethodArgumentResolverCustomizer sortCustomizer() {
    return s -&gt; s.setPropertyDelimiter("&lt;--&gt;");
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>If setting the properties of an existing <code class="notranslate">MethodArgumentResolver</code> is not sufficient for your purpose, extend either <code class="notranslate">SpringDataWebConfiguration</code> or the HATEOAS-enabled equivalent, override the <code class="notranslate">pageableResolver()</code> or <code class="notranslate">sortResolver()</code> methods, and import your customized configuration file instead of using the <code class="notranslate">@Enable</code> annotation.</p>
</div>
<div class="paragraph">
<p>If you need multiple <code class="notranslate">Pageable</code> or <code class="notranslate">Sort</code> instances to be resolved from the request (for multiple tables, for example), you can use Spring’s <code class="notranslate">@Qualifier</code> annotation to distinguish one from another. The request parameters then have to be prefixed with <code class="notranslate">${qualifier}_</code>. The followig example shows the resulting method signature:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight notranslate"><code class="language-java" data-lang="java">String showUsers(Model model,
      @Qualifier("thing1") Pageable first,
      @Qualifier("thing2") Pageable second) { … }</code></pre>
</div>
</div>
<div class="paragraph">
<p>you have to populate <code class="notranslate">thing1_page</code> and <code class="notranslate">thing2_page</code> and so on.</p>
</div>
<div class="paragraph">
<p>The default <code class="notranslate">Pageable</code> passed into the method is equivalent to a <code class="notranslate">PageRequest.of(0, 20)</code> but can be customized by using the <code class="notranslate">@PageableDefault</code> annotation on the <code class="notranslate">Pageable</code> parameter.</p>
</div>
</div>
</div>
<div class="sect4">
<h5 id="core.web.pageables"><a class="anchor" href="#core.web.pageables"></a>Hypermedia Support for Pageables</h5>
<div class="paragraph">
<p>Spring HATEOAS ships with a representation model class (<code class="notranslate">PagedResources</code>) that allows enriching the content of a <code class="notranslate">Page</code> instance with the necessary <code class="notranslate">Page</code> metadata as well as links to let the clients easily navigate the pages. The conversion of a Page to a <code class="notranslate">PagedResources</code> is done by an implementation of the Spring HATEOAS <code class="notranslate">ResourceAssembler</code> interface, called the <code class="notranslate">PagedResourcesAssembler</code>. The following example shows how to use a <code class="notranslate">PagedResourcesAssembler</code> as a controller method argument:</p>
</div>
<div class="exampleblock">
<div class="title">
Example 46. Using a PagedResourcesAssembler as controller method argument
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight notranslate"><code class="language-java" data-lang="java">@Controller
class PersonController {

  @Autowired PersonRepository repository;

  @RequestMapping(value = "/persons", method = RequestMethod.GET)
  HttpEntity&lt;PagedResources&lt;Person&gt;&gt; persons(Pageable pageable,
    PagedResourcesAssembler assembler) {

    Page&lt;Person&gt; persons = repository.findAll(pageable);
    return new ResponseEntity&lt;&gt;(assembler.toResources(persons), HttpStatus.OK);
  }
}</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<p>Enabling the configuration as shown in the preceding example lets the <code class="notranslate">PagedResourcesAssembler</code> be used as a controller method argument. Calling <code class="notranslate">toResources(…)</code> on it has the following effects:</p>
</div>
<div class="ulist">
<ul>
<li> <p>The content of the <code class="notranslate">Page</code> becomes the content of the <code class="notranslate">PagedResources</code> instance.</p> </li>
<li> <p>The <code class="notranslate">PagedResources</code> object gets a <code class="notranslate">PageMetadata</code> instance attached, and it is populated with information from the <code class="notranslate">Page</code> and the underlying <code class="notranslate">PageRequest</code>.</p> </li>
<li> <p>The <code class="notranslate">PagedResources</code> may get <code class="notranslate">prev</code> and <code class="notranslate">next</code> links attached, depending on the page’s state. The links point to the URI to which the method maps. The pagination parameters added to the method match the setup of the <code class="notranslate">PageableHandlerMethodArgumentResolver</code> to make sure the links can be resolved later.</p> </li>
</ul>
</div>
<div class="paragraph">
<p>Assume we have 30 Person instances in the database. You can now trigger a request (<code class="notranslate">GET <a href="javascript:window.open('http://localhost:8080/persons');" class="bare" target="_blank" rel="noopener noreferrer">http://localhost:8080/persons <i class="fa fa-external-link"></i></a></code>) and see output similar to the following:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight notranslate"><code class="language-javascript" data-lang="javascript">{ "links" : [ { "rel" : "next",
                "href" : "http://localhost:8080/persons?page=1&amp;size=20 }
  ],
  "content" : [
     … // 20 Person instances rendered here
  ],
  "pageMetadata" : {
    "size" : 20,
    "totalElements" : 30,
    "totalPages" : 2,
    "number" : 0
  }
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>You see that the assembler produced the correct URI and also picked up the default configuration to resolve the parameters into a <code class="notranslate">Pageable</code> for an upcoming request. This means that, if you change that configuration, the links automatically adhere to the change. By default, the assembler points to the controller method it was invoked in, but that can be customized by handing in a custom <code class="notranslate">Link</code> to be used as base to build the pagination links, which overloads the <code class="notranslate">PagedResourcesAssembler.toResource(…)</code> method.</p>
</div>
</div>
<div class="sect4">
<h5 id="core.web.binding"><a class="anchor" href="#core.web.binding"></a>Web Databinding Support</h5>
<div class="paragraph">
<p>Spring Data projections (described in <a href="#projections">[projections]</a>) can be used to bind incoming request payloads by either using <a href="javascript:window.open('http://goessner.net/articles/JsonPath/');" target="_blank" rel="noopener noreferrer">JSONPath <i class="fa fa-external-link"></i></a> expressions (requires <a href="javascript:window.open('https://github.com/json-path/JsonPath');" target="_blank" rel="noopener noreferrer">Jayway JsonPath <i class="fa fa-external-link"></i></a> or <a href="javascript:window.open('https://www.w3.org/TR/xpath-31/');" target="_blank" rel="noopener noreferrer">XPath <i class="fa fa-external-link"></i></a> expressions (requires <a href="javascript:window.open('https://xmlbeam.org/');" target="_blank" rel="noopener noreferrer">XmlBeam <i class="fa fa-external-link"></i></a>), as shown in the following example:</p>
</div>
<div class="exampleblock">
<div class="title">
Example 47. HTTP payload binding using JSONPath or XPath expressions
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight notranslate"><code class="language-java" data-lang="java">@ProjectedPayload
public interface UserPayload {

  @XBRead("//firstname")
  @JsonPath("$..firstname")
  String getFirstname();

  @XBRead("/lastname")
  @JsonPath({ "$.lastname", "$.user.lastname" })
  String getLastname();
}</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<p>The type shown in the preceding example can be used as a Spring MVC handler method argument or by using <code class="notranslate">ParameterizedTypeReference</code> on one of <code class="notranslate">RestTemplate</code>'s methods. The preceding method declarations would try to find <code class="notranslate">firstname</code> anywhere in the given document. The <code class="notranslate">lastname</code> XML lookup is performed on the top-level of the incoming document. The JSON variant of that tries a top-level <code class="notranslate">lastname</code> first but also tries <code class="notranslate">lastname</code> nested in a <code class="notranslate">user</code> sub-document if the former does not return a value. That way, changes in the structure of the source document can be mitigated easily without having clients calling the exposed methods (usually a drawback of class-based payload binding).</p>
</div>
<div class="paragraph">
<p>Nested projections are supported as described in <a href="#projections">[projections]</a>. If the method returns a complex, non-interface type, a Jackson <code class="notranslate">ObjectMapper</code> is used to map the final value.</p>
</div>
<div class="paragraph">
<p>For Spring MVC, the necessary converters are registered automatically as soon as <code class="notranslate">@EnableSpringDataWebSupport</code> is active and the required dependencies are available on the classpath. For usage with <code class="notranslate">RestTemplate</code>, register a <code class="notranslate">ProjectingJackson2HttpMessageConverter</code> (JSON) or <code class="notranslate">XmlBeamHttpMessageConverter</code> manually.</p>
</div>
<div class="paragraph">
<p>For more information, see the <a href="javascript:window.open('https://github.com/spring-projects/spring-data-examples/tree/master/web/projection');" target="_blank" rel="noopener noreferrer">web projection example <i class="fa fa-external-link"></i></a> in the canonical <a href="javascript:window.open('https://github.com/spring-projects/spring-data-examples');" target="_blank" rel="noopener noreferrer">Spring Data Examples repository <i class="fa fa-external-link"></i></a>.</p>
</div>
</div>
<div class="sect4">
<h5 id="core.web.type-safe"><a class="anchor" href="#core.web.type-safe"></a>Querydsl Web Support</h5>
<div class="paragraph">
<p>For those stores having <a href="javascript:window.open('http://www.querydsl.com/');" target="_blank" rel="noopener noreferrer">QueryDSL <i class="fa fa-external-link"></i></a> integration, it is possible to derive queries from the attributes contained in a <code class="notranslate">Request</code> query string.</p>
</div>
<div class="paragraph">
<p>Consider the following query string:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight notranslate"><code class="language-text" data-lang="text">?firstname=Dave&amp;lastname=Matthews</code></pre>
</div>
</div>
<div class="paragraph">
<p>Given the <code class="notranslate">User</code> object from previous examples, a query string can be resolved to the following value by using the <code class="notranslate">QuerydslPredicateArgumentResolver</code>.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight notranslate"><code class="language-text" data-lang="text">QUser.user.firstname.eq("Dave").and(QUser.user.lastname.eq("Matthews"))</code></pre>
</div>
</div>
<div class="admonitionblock note">
<table>
<tbody>
<tr>
<td class="icon"> <i class="fa icon-note" title="Note"></i> </td>
<td class="content"> The feature is automatically enabled, along with <code class="notranslate">@EnableSpringDataWebSupport</code>, when Querydsl is found on the classpath. </td>
</tr>
</tbody>
</table>
</div>
<div class="paragraph">
<p>Adding a <code class="notranslate">@QuerydslPredicate</code> to the method signature provides a ready-to-use <code class="notranslate">Predicate</code>, which can be run by using the <code class="notranslate">QuerydslPredicateExecutor</code>.</p>
</div>
<div class="admonitionblock tip">
<table>
<tbody>
<tr>
<td class="icon"> <i class="fa icon-tip" title="Tip"></i> </td>
<td class="content"> Type information is typically resolved from the method’s return type. Since that information does not necessarily match the domain type, it might be a good idea to use the <code class="notranslate">root</code> attribute of <code class="notranslate">QuerydslPredicate</code>. </td>
</tr>
</tbody>
</table>
</div>
<div class="paragraph">
<p>The following exampe shows how to use <code class="notranslate">@QuerydslPredicate</code> in a method signature:</p>
</div>
<div class="exampleblock">
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight notranslate"><code class="language-java" data-lang="java">@Controller
class UserController {

  @Autowired UserRepository repository;

  @RequestMapping(value = "/", method = RequestMethod.GET)
  String index(Model model, @QuerydslPredicate(root = User.class) Predicate predicate,    <i class="conum" data-value="1"></i><b>(1)</b>
          Pageable pageable, @RequestParam MultiValueMap&lt;String, String&gt; parameters) {

    model.addAttribute("users", repository.findAll(predicate, pageable));

    return "index";
  }
}</code></pre>
</div>
</div>
<div class="colist arabic">
<table>
<tbody>
<tr>
<td><i class="conum" data-value="1"></i><b class="notranslate">1</b></td>
<td>Resolve query string arguments to matching <code class="notranslate">Predicate</code> for <code class="notranslate">User</code>.</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<div class="paragraph">
<p>The default binding is as follows:</p>
</div>
<div class="ulist">
<ul>
<li> <p><code class="notranslate">Object</code> on simple properties as <code class="notranslate">eq</code>.</p> </li>
<li> <p><code class="notranslate">Object</code> on collection like properties as <code class="notranslate">contains</code>.</p> </li>
<li> <p><code class="notranslate">Collection</code> on simple properties as <code class="notranslate">in</code>.</p> </li>
</ul>
</div>
<div class="paragraph">
<p>Those bindings can be customized through the <code class="notranslate">bindings</code> attribute of <code class="notranslate">@QuerydslPredicate</code> or by making use of Java 8 <code class="notranslate">default methods</code> and adding the <code class="notranslate">QuerydslBinderCustomizer</code> method to the repository interface.</p>
</div>
<div class="exampleblock">
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight notranslate"><code class="language-java" data-lang="java">interface UserRepository extends CrudRepository&lt;User, String&gt;,
                                 QuerydslPredicateExecutor&lt;User&gt;,                <i class="conum" data-value="1"></i><b>(1)</b>
                                 QuerydslBinderCustomizer&lt;QUser&gt; {               <i class="conum" data-value="2"></i><b>(2)</b>

  @Override
  default void customize(QuerydslBindings bindings, QUser user) {

    bindings.bind(user.username).first((path, value) -&gt; path.contains(value))    <i class="conum" data-value="3"></i><b>(3)</b>
    bindings.bind(String.class)
      .first((StringPath path, String value) -&gt; path.containsIgnoreCase(value)); <i class="conum" data-value="4"></i><b>(4)</b>
    bindings.excluding(user.password);                                           <i class="conum" data-value="5"></i><b>(5)</b>
  }
}</code></pre>
</div>
</div>
<div class="colist arabic">
<table>
<tbody>
<tr>
<td><i class="conum" data-value="1"></i><b class="notranslate">1</b></td>
<td><code class="notranslate">QuerydslPredicateExecutor</code> provides access to specific finder methods for <code class="notranslate">Predicate</code>.</td>
</tr>
<tr>
<td><i class="conum" data-value="2"></i><b class="notranslate">2</b></td>
<td><code class="notranslate">QuerydslBinderCustomizer</code> defined on the repository interface is automatically picked up and shortcuts <code class="notranslate">@QuerydslPredicate(bindings=…)</code>.</td>
</tr>
<tr>
<td><i class="conum" data-value="3"></i><b class="notranslate">3</b></td>
<td>Define the binding for the <code class="notranslate">username</code> property to be a simple <code class="notranslate">contains</code> binding.</td>
</tr>
<tr>
<td><i class="conum" data-value="4"></i><b class="notranslate">4</b></td>
<td>Define the default binding for <code class="notranslate">String</code> properties to be a case-insensitive <code class="notranslate">contains</code> match.</td>
</tr>
<tr>
<td><i class="conum" data-value="5"></i><b class="notranslate">5</b></td>
<td>Exclude the <code class="notranslate">password</code> property from <code class="notranslate">Predicate</code> resolution.</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
<div class="sect3">
<h4 id="core.repository-populators"><a class="anchor" href="#core.repository-populators"></a>3.8.3. Repository Populators</h4>
<div class="paragraph">
<p>If you work with the Spring JDBC module, you are probably familiar with the support to populate a <code class="notranslate">DataSource</code> with SQL scripts. A similar abstraction is available on the repositories level, although it does not use SQL as the data definition language because it must be store-independent. Thus, the populators support XML (through Spring’s OXM abstraction) and JSON (through Jackson) to define data with which to populate the repositories.</p>
</div>
<div class="paragraph">
<p>Assume you have a file <code class="notranslate">data.json</code> with the following content:</p>
</div>
<div class="exampleblock">
<div class="title">
Example 48. Data defined in JSON
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight notranslate"><code class="language-javascript" data-lang="javascript">[ { "_class" : "com.acme.Person",
 "firstname" : "Dave",
  "lastname" : "Matthews" },
  { "_class" : "com.acme.Person",
 "firstname" : "Carter",
  "lastname" : "Beauford" } ]</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<p>You can populate your repositories by using the populator elements of the repository namespace provided in Spring Data Commons. To populate the preceding data to your PersonRepository, declare a populator similar to the following:</p>
</div>
<div class="exampleblock">
<div class="title">
Example 49. Declaring a Jackson repository populator
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight notranslate"><code class="language-xml" data-lang="xml">&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;beans xmlns="http://www.springframework.org/schema/beans"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:repository="http://www.springframework.org/schema/data/repository"
  xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/data/repository
    http://www.springframework.org/schema/data/repository/spring-repository.xsd"&gt;

  &lt;repository:jackson2-populator locations="classpath:data.json" /&gt;

&lt;/beans&gt;</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<p>The preceding declaration causes the <code class="notranslate">data.json</code> file to be read and deserialized by a Jackson <code class="notranslate">ObjectMapper</code>.</p>
</div>
<div class="paragraph">
<p>The type to which the JSON object is unmarshalled is determined by inspecting the <code class="notranslate">_class</code> attribute of the JSON document. The infrastructure eventually selects the appropriate repository to handle the object that was deserialized.</p>
</div>
<div class="paragraph">
<p>To instead use XML to define the data the repositories should be populated with, you can use the <code class="notranslate">unmarshaller-populator</code> element. You configure it to use one of the XML marshaller options available in Spring OXM. See the <a href="javascript:window.open('https://docs.spring.io/spring/docs/5.1.5.RELEASE/spring-framework-reference/data-access.html#oxm');" target="_blank" rel="noopener noreferrer">Spring reference documentation <i class="fa fa-external-link"></i></a> for details. The following example shows how to unmarshal a repository populator with JAXB:</p>
</div>
<div class="exampleblock">
<div class="title">
Example 50. Declaring an unmarshalling repository populator (using JAXB)
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight notranslate"><code class="language-xml" data-lang="xml">&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;beans xmlns="http://www.springframework.org/schema/beans"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:repository="http://www.springframework.org/schema/data/repository"
  xmlns:oxm="http://www.springframework.org/schema/oxm"
  xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/data/repository
    http://www.springframework.org/schema/data/repository/spring-repository.xsd
    http://www.springframework.org/schema/oxm
    http://www.springframework.org/schema/oxm/spring-oxm.xsd"&gt;

  &lt;repository:unmarshaller-populator locations="classpath:data.json"
    unmarshaller-ref="unmarshaller" /&gt;

  &lt;oxm:jaxb2-marshaller contextPath="com.acme" /&gt;

&lt;/beans&gt;</code></pre>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<h2 id="reference" class="sect0"><a class="anchor" href="#reference"></a>Reference Documentation</h2>
<div class="sect1">
<h2 id="jdbc.repositories"><a class="anchor" href="#jdbc.repositories"></a>4. JDBC Repositories</h2>
<div class="sectionbody">
<div class="paragraph">
<p>This chapter points out the specialties for repository support for JDBC. This builds on the core repository support explained in <a href="#repositories">Working with Spring Data Repositories</a>. You should have a sound understanding of the basic concepts explained there.</p>
</div>
<div class="sect3">
<h4 id="jdbc.why"><a class="anchor" href="#jdbc.why"></a>4.1. Why Spring Data JDBC?</h4>
<div class="paragraph">
<p>The main persistence API for relational databases in the Java world is certainly JPA, which has its own Spring Data module. Why is there another one?</p>
</div>
<div class="paragraph">
<p>JPA does a lot of things in order to help the developer. Among other things, it tracks changes to entities. It does lazy loading for you. It lets you map a wide array of object constructs to an equally wide array of database designs.</p>
</div>
<div class="paragraph">
<p>This is great and makes a lot of things really easy. Just take a look at a basic JPA tutorial. But it often gets really confusing as to why JPA does a certain thing. Also, things that are really simple conceptually get rather difficult with JPA.</p>
</div>
<div class="paragraph">
<p>Spring Data JDBC aims to be much simpler conceptually, by embracing the following design decisions:</p>
</div>
<div class="ulist">
<ul>
<li> <p>If you load an entity, SQL statements get executed. Once this is done, you have a completely loaded entity. No lazy loading or caching is done.</p> </li>
<li> <p>If you save an entity, it gets saved. If you do not, it does not. There is no dirty tracking and no session.</p> </li>
<li> <p>There is a simple model of how to map entities to tables. It probably only works for rather simple cases. If you do not like that, you should code your own strategy. Spring Data JDBC offers only very limited support for customizing the strategy with annotations.</p> </li>
</ul>
</div>
</div>
<div class="sect3">
<h4 id="jdbc.domain-driven-design"><a class="anchor" href="#jdbc.domain-driven-design"></a>4.2. Domain Driven Design and Relational Databases.</h4>
<div class="paragraph">
<p>All Spring Data modules are inspired by the concepts of “repository”, “aggregate”, and “aggregate root” from Domain Driven Design. These are possibly even more important for Spring Data JDBC, because they are, to some extent, contrary to normal practice when working with relational databases.</p>
</div>
<div class="paragraph">
<p>An aggregate is a group of entities that is guaranteed to be consistent between atomic changes to it. A classic example is an <code class="notranslate">Order</code> with <code class="notranslate">OrderItems</code>. A property on <code class="notranslate">Order</code> (for example, <code class="notranslate">numberOfItems</code> is consistent with the actual number of <code class="notranslate">OrderItems</code>) remains consistent as changes are made.</p>
</div>
<div class="paragraph">
<p>References across aggregates are not guaranteed to be consistent at all times. They are guaranteed to become consistent eventually.</p>
</div>
<div class="paragraph">
<p>Each aggregate has exactly one aggregate root, which is one of the entities of the aggregate. The aggregate gets manipulated only through methods on that aggregate root. These are the atomic changes mentioned earlier.</p>
</div>
<div class="paragraph">
<p>A repository is an abstraction over a persistent store that looks like a collection of all the aggregates of a certain type. For Spring Data in general, this means you want to have one <code class="notranslate">Repository</code> per aggregate root. In addition, for Spring Data JDBC this means that all entities reachable from an aggregate root are considered to be part of that aggregate root. Spring Data JDBC assumes that only the aggregate has a foreign key to a table storing non-root entities of the aggregate and no other entity points toward non-root entities.</p>
</div>
<div class="admonitionblock warning">
<table>
<tbody>
<tr>
<td class="icon"> <i class="fa icon-warning" title="Warning"></i> </td>
<td class="content"> In the current implementation, entities referenced from an aggregate root are deleted and recreated by Spring Data JDBC. </td>
</tr>
</tbody>
</table>
</div>
<div class="paragraph">
<p>You can overwrite the repository methods with implementations that match your style of working and designing your database.</p>
</div>
</div>
<div class="sect3">
<h4 id="jdbc.java-config"><a class="anchor" href="#jdbc.java-config"></a>4.3. Annotation-based Configuration</h4>
<div class="paragraph">
<p>The Spring Data JDBC repositories support can be activated by an annotation through Java configuration, as the following example shows:</p>
</div>
<div class="exampleblock">
<div class="title">
Example 51. Spring Data JDBC repositories using Java configuration
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight notranslate"><code class="language-java" data-lang="java">@Configuration
@EnableJdbcRepositories
class ApplicationConfig {

  @Bean
  public DataSource dataSource() {

    EmbeddedDatabaseBuilder builder = new EmbeddedDatabaseBuilder();
    return builder.setType(EmbeddedDatabaseType.HSQL).build();
  }

}</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<p>The configuration class in the preceding example sets up an embedded HSQL database by using the <code class="notranslate">EmbeddedDatabaseBuilder</code> API of <code class="notranslate">spring-jdbc</code>. We activate Spring Data JDBC repositories by using the <code class="notranslate">@EnableJdbcRepositories</code>. If no base package is configured, it uses the package in which the configuration class resides.</p>
</div>
</div>
<div class="sect2">
<h3 id="jdbc.entity-persistence"><a class="anchor" href="#jdbc.entity-persistence"></a>4.4. Persisting Entities</h3>
<div class="paragraph">
<p>Saving an aggregate can be performed with the <code class="notranslate">CrudRepository.save(…)</code> method. If the aggregate is new, this results in an insert for the aggregate root, followed by insert statements for all directly or indirectly referenced entities.</p>
</div>
<div class="paragraph">
<p>If the aggregate root is not new, all referenced entities get deleted, the aggregate root gets updated, and all referenced entities get inserted again. Note that whether an instance is new is part of the instance’s state.</p>
</div>
<div class="admonitionblock note">
<table>
<tbody>
<tr>
<td class="icon"> <i class="fa icon-note" title="Note"></i> </td>
<td class="content"> This approach has some obvious downsides. If only few of the referenced entities have been actually changed, the deletion and insertion is wasteful. While this process could and probably will be improved, there are certain limitations to what Spring Data JDBC can offer. It does not know the previous state of an aggregate. So any update process always has to take whatever it finds in the database and make sure it converts it to whatever is the state of the entity passed to the save method. </td>
</tr>
</tbody>
</table>
</div>
<div class="sect3">
<h4 id="mapping.fundamentals"><a class="anchor" href="#mapping.fundamentals"></a>4.4.1. Object Mapping Fundamentals</h4>
<div class="paragraph">
<p>This section covers the fundamentals of Spring Data object mapping, object creation, field and property access, mutability and immutability. Note, that this section only applies to Spring Data modules that do not use the object mapping of the underlying data store (like JPA). Also be sure to consult the store-specific sections for store-specific object mapping, like indexes, customizing column or field names or the like.</p>
</div>
<div class="paragraph">
<p>Core responsibility of the Spring Data object mapping is to create instances of domain objects and map the store-native data structures onto those. This means we need two fundamental steps:</p>
</div>
<div class="olist arabic">
<ol class="arabic">
<li> <p>Instance creation by using one of the constructors exposed.</p> </li>
<li> <p>Instance population to materialize all exposed properties.</p> </li>
</ol>
</div>
<div class="sect4">
<h5 id="mapping.object-creation"><a class="anchor" href="#mapping.object-creation"></a>Object creation</h5>
<div class="paragraph">
<p>Spring Data automatically tries to detect a persistent entity’s constructor to be used to materialize objects of that type. The resolution algorithm works as follows:</p>
</div>
<div class="olist arabic">
<ol class="arabic">
<li> <p>If there’s a no-argument constructor, it will be used. Other constructors will be ignored.</p> </li>
<li> <p>If there’s a single constructor taking arguments, it will be used.</p> </li>
<li> <p>If there are multiple constructors taking arguments, the one to be used by Spring Data will have to be annotated with <code class="notranslate">@PersistenceConstructor</code>.</p> </li>
</ol>
</div>
<div class="paragraph">
<p>The value resolution assumes constructor argument names to match the property names of the entity, i.e. the resolution will be performed as if the property was to be populated, including all customizations in mapping (different datastore column or field name etc.). This also requires either parameter names information available in the class file or an <code class="notranslate">@ConstructorProperties</code> annotation being present on the constructor.</p>
</div>
<div class="paragraph">
<p>The value resolution can be customized by using Spring Framework’s <code class="notranslate">@Value</code> value annotation using a store-specific SpEL expression. Please consult the section on store specific mappings for further details.</p>
</div>
<div id="mapping.object-creation.details" class="sidebarblock">
<div class="content">
<div class="title">
Object creation internals
</div>
<div class="paragraph">
<p>To avoid the overhead of reflection, Spring Data object creation uses a factory class generated at runtime by default, which will call the domain classes constructor directly. I.e. for this example type:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight notranslate"><code class="language-java" data-lang="java">class Person {
  Person(String firstname, String lastname) { … }
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>we will create a factory class semantically equivalent to this one at runtime:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight notranslate"><code class="language-java" data-lang="java">class PersonObjectInstantiator implements ObjectInstantiator {

  Object newInstance(Object... args) {
    return new Person((String) args[0], (String) args[1]);
  }
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>This gives us a roundabout 10% performance boost over reflection. For the domain class to be eligible for such optimization, it needs to adhere to a set of constraints:</p>
</div>
<div class="ulist">
<ul>
<li> <p>it must not be a private class</p> </li>
<li> <p>it must not be a non-static inner class</p> </li>
<li> <p>it must not be a CGLib proxy class</p> </li>
<li> <p>the constructor to be used by Spring Data must not be private</p> </li>
</ul>
</div>
<div class="paragraph">
<p>If any of these criteria match, Spring Data will fall back to entity instantiation via reflection.</p>
</div>
</div>
</div>
</div>
<div class="sect4">
<h5 id="mapping.property-population"><a class="anchor" href="#mapping.property-population"></a>Property population</h5>
<div class="paragraph">
<p>Once an instance of the entity has been created, Spring Data populates all remaining persistent properties of that class. Unless already populated by the entity’s constructor (i.e. consumed through its constructor argument list), the identifier property will be populated first to allow the resolution of cyclic object references. After that, all non-transient properties that have not already been populated by the constructor are set on the entity instance. For that we use the following algorithm:</p>
</div>
<div class="olist arabic">
<ol class="arabic">
<li> <p>If the property is immutable but exposes a wither method (see below), we use the wither to create a new entity instance with the new property value.</p> </li>
<li> <p>If property access (i.e. access through getters and setters) is defined, we’re invoking the setter method.</p> </li>
<li> <p>By default, we set the field value directly.</p> </li>
</ol>
</div>
<div id="mapping.property-population.details" class="sidebarblock">
<div class="content">
<div class="title">
Property population internals
</div>
<div class="paragraph">
<p>Similarly to our <a href="#mapping.object-creation.details">optimizations in object construction</a> we also use Spring Data runtime generated accessor classes to interact with the entity instance.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight notranslate"><code class="language-java" data-lang="java">class Person {

  private final Long id;
  private String firstname;
  private @AccessType(Type.PROPERTY) String lastname;

  Person() {
    this.id = null;
  }

  Person(Long id, String firstname, String lastname) {
    // Field assignments
  }

  Person withId(Long id) {
    return new Person(id, this.firstname, this.lastame);
  }

  void setLastname(String lastname) {
    this.lastname = lastname;
  }
}</code></pre>
</div>
</div>
<div class="exampleblock">
<div class="title">
Example 52. A generated Property Accessor
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight notranslate"><code class="language-java" data-lang="java">class PersonPropertyAccessor implements PersistentPropertyAccessor {

  private static final MethodHandle firstname;              <i class="conum" data-value="2"></i><b>(2)</b>

  private Person person;                                    <i class="conum" data-value="1"></i><b>(1)</b>

  public void setProperty(PersistentProperty property, Object value) {

    String name = property.getName();

    if ("firstname".equals(name)) {
      firstname.invoke(person, (String) value);             <i class="conum" data-value="2"></i><b>(2)</b>
    } else if ("id".equals(name)) {
      this.person = person.withId((Long) value);            <i class="conum" data-value="3"></i><b>(3)</b>
    } else if ("lastname".equals(name)) {
      this.person.setLastname((String) value);              <i class="conum" data-value="4"></i><b>(4)</b>
    }
  }
}</code></pre>
</div>
</div>
<div class="colist arabic">
<table>
<tbody>
<tr>
<td><i class="conum" data-value="1"></i><b class="notranslate">1</b></td>
<td>PropertyAccessor’s hold a mutable instance of the underlying object. This is, to enable mutations of otherwise immutable properties.</td>
</tr>
<tr>
<td><i class="conum" data-value="2"></i><b class="notranslate">2</b></td>
<td>By default, Spring Data uses field-access to read and write property values. As per visibility rules of <code class="notranslate">private</code> fields, <code class="notranslate">MethodHandles</code> are used to interact with fields.</td>
</tr>
<tr>
<td><i class="conum" data-value="3"></i><b class="notranslate">3</b></td>
<td>The class exposes a <code class="notranslate">withId(…)</code> method that’s used to set the identifier, e.g. when an instance is inserted into the datastore and an identifier has been generated. Calling <code class="notranslate">withId(…)</code> creates a new <code class="notranslate">Person</code> object. All subsequent mutations will take place in the new instance leaving the previous untouched.</td>
</tr>
<tr>
<td><i class="conum" data-value="4"></i><b class="notranslate">4</b></td>
<td>Using property-access allows direct method invocations without using <code class="notranslate">MethodHandles</code>.</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<div class="paragraph">
<p>This gives us a roundabout 25% performance boost over reflection. For the domain class to be eligible for such optimization, it needs to adhere to a set of constraints:</p>
</div>
<div class="ulist">
<ul>
<li> <p>Types must not reside in the default or under the <code class="notranslate">java</code> package.</p> </li>
<li> <p>Types and their constructors must be <code class="notranslate">public</code></p> </li>
<li> <p>Types that are inner classes must be <code class="notranslate">static</code>.</p> </li>
<li> <p>The used Java Runtime must allow for declaring classes in the originating <code class="notranslate">ClassLoader</code>. Java 9 and newer impose certain limitations.</p> </li>
</ul>
</div>
<div class="paragraph">
<p>By default, Spring Data attempts to use generated property accessors and falls back to reflection-based ones if a limitation is detected.</p>
</div>
</div>
</div>
<div class="paragraph">
<p>Let’s have a look at the following entity:</p>
</div>
<div class="exampleblock">
<div class="title">
Example 53. A sample entity
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight notranslate"><code class="language-java" data-lang="java">class Person {

  private final @Id Long id;                                                <i class="conum" data-value="1"></i><b>(1)</b>
  private final String firstname, lastname;                                 <i class="conum" data-value="2"></i><b>(2)</b>
  private final LocalDate birthday;
  private final int age; <i class="conum" data-value="3"></i><b>(3)</b>

  private String comment;                                                   <i class="conum" data-value="4"></i><b>(4)</b>
  private @AccessType(Type.PROPERTY) String remarks;                        <i class="conum" data-value="5"></i><b>(5)</b>

  static Person of(String firstname, String lastname, LocalDate birthday) { <i class="conum" data-value="6"></i><b>(6)</b>

    return new Person(null, firstname, lastname, birthday,
      Period.between(birthday, LocalDate.now()).getYears());
  }

  Person(Long id, String firstname, String lastname, LocalDate birthday, int age) { <i class="conum" data-value="6"></i><b>(6)</b>

    this.id = id;
    this.firstname = firstname;
    this.lastname = lastname;
    this.birthday = birthday;
    this.age = age;
  }

  Person withId(Long id) {                                                  <i class="conum" data-value="1"></i><b>(1)</b>
    return new Person(id, this.firstname, this.lastname, this.birthday);
  }

  void setRemarks(String remarks) {                                         <i class="conum" data-value="5"></i><b>(5)</b>
    this.remarks = remarks;
  }
}</code></pre>
</div>
</div>
</div>
</div>
<div class="colist arabic">
<table>
<tbody>
<tr>
<td><i class="conum" data-value="1"></i><b class="notranslate">1</b></td>
<td>The identifier property is final but set to <code class="notranslate">null</code> in the constructor. The class exposes a <code class="notranslate">withId(…)</code> method that’s used to set the identifier, e.g. when an instance is inserted into the datastore and an identifier has been generated. The original <code class="notranslate">Person</code> instance stays unchanged as a new one is created. The same pattern is usually applied for other properties that are store managed but might have to be changed for persistence operations.</td>
</tr>
<tr>
<td><i class="conum" data-value="2"></i><b class="notranslate">2</b></td>
<td>The <code class="notranslate">firstname</code> and <code class="notranslate">lastname</code> properties are ordinary immutable properties potentially exposed through getters.</td>
</tr>
<tr>
<td><i class="conum" data-value="3"></i><b class="notranslate">3</b></td>
<td>The <code class="notranslate">age</code> property is an immutable but derived one from the <code class="notranslate">birthday</code> property. With the design shown, the database value will trump the defaulting as Spring Data uses the only declared constructor. Even if the intent is that the calculation should be preferred, it’s important that this constructor also takes <code class="notranslate">age</code> as parameter (to potentially ignore it) as otherwise the property population step will attempt to set the age field and fail due to it being immutable and no wither being present.</td>
</tr>
<tr>
<td><i class="conum" data-value="4"></i><b class="notranslate">4</b></td>
<td>The <code class="notranslate">comment</code> property is mutable is populated by setting its field directly.</td>
</tr>
<tr>
<td><i class="conum" data-value="5"></i><b class="notranslate">5</b></td>
<td>The <code class="notranslate">remarks</code> properties are mutable and populated by setting the <code class="notranslate">comment</code> field directly or by invoking the setter method for</td>
</tr>
<tr>
<td><i class="conum" data-value="6"></i><b class="notranslate">6</b></td>
<td>The class exposes a factory method and a constructor for object creation. The core idea here is to use factory methods instead of additional constructors to avoid the need for constructor disambiguation through <code class="notranslate">@PersistenceConstructor</code>. Instead, defaulting of properties is handled within the factory method.</td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="sect4">
<h5 id="_general_recommendations"><a class="anchor" href="#_general_recommendations"></a>General recommendations</h5>
<div class="ulist">
<ul>
<li> <p><em>Try to stick to immutable objects</em> — Immutable objects are straightforward to create as materializing an object is then a matter of calling its constructor only. Also, this avoids your domain objects to be littered with setter methods that allow client code to manipulate the objects state. If you need those, prefer to make them package protected so that they can only be invoked by a limited amount of co-located types. Constructor-only materialization is up to 30% faster than properties population.</p> </li>
<li> <p><em>Provide an all-args constructor</em> — Even if you cannot or don’t want to model your entities as immutable values, there’s still value in providing a constructor that takes all properties of the entity as arguments, including the mutable ones, as this allows the object mapping to skip the property population for optimal performance.</p> </li>
<li> <p><em>Use factory methods instead of overloaded constructors to avoid <code class="notranslate">@PersistenceConstructor</code></em> — With an all-argument constructor needed for optimal performance, we usually want to expose more application use case specific constructors that omit things like auto-generated identifiers etc. It’s an established pattern to rather use static factory methods to expose these variants of the all-args constructor.</p> </li>
<li> <p><em>Make sure you adhere to the constraints that allow the generated instantiator and property accessor classes to be used</em> — </p> </li>
<li> <p><em>For identifiers to be generated, still use a final field in combination with a wither method</em> — </p> </li>
<li> <p><em>Use Lombok to avoid boilerplate code</em> — As persistence operations usually require a constructor taking all arguments, their declaration becomes a tedious repetition of boilerplate parameter to field assignments that can best be avoided by using Lombok’s <code class="notranslate">@AllArgsConstructor</code>.</p> </li>
</ul>
</div>
</div>
<div class="sect4">
<h5 id="_kotlin_support"><a class="anchor" href="#_kotlin_support"></a>Kotlin support</h5>
<div class="paragraph">
<p>Spring Data adapts specifics of Kotlin to allow object creation and mutation.</p>
</div>
<div class="sect5">
<h6 id="_kotlin_object_creation"><a class="anchor" href="#_kotlin_object_creation"></a>Kotlin object creation</h6>
<div class="paragraph">
<p>Kotlin classes are supported to be instantiated , all classes are immutable by default and require explicit property declarations to define mutable properties. Consider the following <code class="notranslate">data</code> class <code class="notranslate">Person</code>:</p>
</div>
<div class="exampleblock">
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight notranslate"><code class="language-java" data-lang="java">data class Person(val id: String, val name: String)</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<p>The class above compiles to a typical class with an explicit constructor. We can customize this class by adding another constructor and annotate it with <code class="notranslate">@PersistenceConstructor</code> to indicate a constructor preference:</p>
</div>
<div class="exampleblock">
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight notranslate"><code class="language-java" data-lang="java">data class Person(var id: String, val name: String) {

    @PersistenceConstructor
    constructor(id: String) : this(id, "unknown")
}</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<p>Kotlin supports parameter optionality by allowing default values to be used if a parameter is not provided. When Spring Data detects a constructor with parameter defaulting, then it leaves these parameters absent if the data store does not provide a value (or simply returns <code class="notranslate">null</code>) so Kotlin can apply parameter defaulting. Consider the following class that applies parameter defaulting for <code class="notranslate">name</code></p>
</div>
<div class="exampleblock">
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight notranslate"><code class="language-java" data-lang="java">data class Person(var id: String, val name: String = "unknown")</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<p>Every time the <code class="notranslate">name</code> parameter is either not part of the result or its value is <code class="notranslate">null</code>, then the <code class="notranslate">name</code> defaults to <code class="notranslate">unknown</code>.</p>
</div>
</div>
<div class="sect5">
<h6 id="_property_population_of_kotlin_data_classes"><a class="anchor" href="#_property_population_of_kotlin_data_classes"></a>Property population of Kotlin data classes</h6>
<div class="paragraph">
<p>In Kotlin, all classes are immutable by default and require explicit property declarations to define mutable properties. Consider the following <code class="notranslate">data</code> class <code class="notranslate">Person</code>:</p>
</div>
<div class="exampleblock">
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight notranslate"><code class="language-java" data-lang="java">data class Person(val id: String, val name: String)</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<p>This class is effectively immutable. It allows to create new instances as Kotlin generates a <code class="notranslate">copy(…)</code> method that creates new object instances copying all property values from the existing object and applying property values provided as arguments to the method.</p>
</div>
</div>
</div>
</div>
<div class="sect3">
<h4 id="jdbc.entity-persistence.types"><a class="anchor" href="#jdbc.entity-persistence.types"></a>4.4.2. Supported Types in Your Entity</h4>
<div class="paragraph">
<p>The properties of the following types are currently supported:</p>
</div>
<div class="ulist">
<ul>
<li> <p>All primitive types and their boxed types (<code class="notranslate">int</code>, <code class="notranslate">float</code>, <code class="notranslate">Integer</code>, <code class="notranslate">Float</code>, and so on)</p> </li>
<li> <p>Enums get mapped to their name.</p> </li>
<li> <p><code class="notranslate">String</code></p> </li>
<li> <p><code class="notranslate">java.util.Date</code>, <code class="notranslate">java.time.LocalDate</code>, <code class="notranslate">java.time.LocalDateTime</code>, and <code class="notranslate">java.time.LocalTime</code></p> </li>
<li> <p>Anything your database driver accepts.</p> </li>
<li> <p>References to other entities. They are considered a one-to-one relationship. It is optional for such entities to have an <code class="notranslate">id</code> attribute. The table of the referenced entity is expected to have an additional column named the same as the table of the referencing entity. You can change this name by implementing <code class="notranslate">NamingStrategy.getReverseColumnName(RelationalPersistentProperty property)</code>.</p> </li>
<li> <p><code class="notranslate">Set&lt;some entity&gt;</code> is considered a one-to-many relationship. The table of the referenced entity is expected to have an additional column named the same as the table of the referencing entity. You can change this name by implementing <code class="notranslate">NamingStrategy.getReverseColumnName(RelationalPersistentProperty property)</code>.</p> </li>
<li> <p><code class="notranslate">Map&lt;simple type, some entity&gt;</code> is considered a qualified one-to-many relationship. The table of the referenced entity is expected to have two additional columns: One named the same as the table of the referencing entity for the foreign key and one with the same name and an additional <code class="notranslate">_key</code> suffix for the map key. You can change this behavior by implementing <code class="notranslate">NamingStrategy.getReverseColumnName(RelationalPersistentProperty property)</code> and <code class="notranslate">NamingStrategy.getKeyColumn(RelationalPersistentProperty property)</code>, respectively. Alternatively you may annotate the attribute with <code class="notranslate">@Column(value="your_column_name", keyColumn="your_key_column_name")</code></p> </li>
<li> <p><code class="notranslate">List&lt;some entity&gt;</code> is mapped as a <code class="notranslate">Map&lt;Integer, some entity&gt;</code>.</p> </li>
</ul>
</div>
<div class="paragraph">
<p>The handling of referenced entities is limited. This is based on the idea of aggregate roots as described above. If you reference another entity, that entity is, by definition, part of your aggregate. So, if you remove the reference, the previously referenced entity gets deleted. This also means references are 1-1 or 1-n, but not n-1 or n-m.</p>
</div>
<div class="paragraph">
<p>If you have n-1 or n-m references, you are, by definition, dealing with two separate aggregates. References between those should be encoded as simple <code class="notranslate">id</code> values, which should map properly with Spring Data JDBC.</p>
</div>
</div>
<div class="sect3">
<h4 id="jdbc.entity-persistence.custom-converters"><a class="anchor" href="#jdbc.entity-persistence.custom-converters"></a>4.4.3. Custom converters</h4>
<div class="paragraph">
<p>Custom converters can be registered, for types that are not supported by default, by inheriting your configuration from <code class="notranslate">JdbcConfiguration</code> and overwriting the method <code class="notranslate">jdbcCustomConversions()</code>.</p>
</div>
<div class="exampleblock">
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight notranslate"><code class="language-java" data-lang="java">@Configuration
public class DataJdbcConfiguration extends JdbcConfiguration {

    @Override
    protected JdbcCustomConversions jdbcCustomConversions() {

      return new JdbcCustomConversions(Collections.singletonList(TimestampTzToDateConverter.INSTANCE));

    }

    @ReadingConverter
    enum TimestampTzToDateConverter implements Converter&lt;TIMESTAMPTZ, Date&gt; {

        INSTANCE;

        @Override
        public Date convert(TIMESTAMPTZ source) {
            //...
        }
    }
}</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<p>The constructor of <code class="notranslate">JdbcCustomConversions</code> accepts a list of <code class="notranslate">org.springframework.core.convert.converter.Converter</code>.</p>
</div>
<div class="paragraph">
<p>Converters should be annotated with <code class="notranslate">@ReadingConverter</code> or <code class="notranslate">@WritingConverter</code> in order to control their applicability to only reading from or to writing to the database.</p>
</div>
<div class="paragraph">
<p><code class="notranslate">TIMESTAMPTZ</code> in the example is a database specific data type that needs conversion into something more suitable for a domain model.</p>
</div>
</div>
<div class="sect3">
<h4 id="jdbc.entity-persistence.naming-strategy"><a class="anchor" href="#jdbc.entity-persistence.naming-strategy"></a>4.4.4. <code class="notranslate">NamingStrategy</code></h4>
<div class="paragraph">
<p>When you use the standard implementations of <code class="notranslate">CrudRepository</code> that Spring Data JDBC provides, they expect a certain table structure. You can tweak that by providing a <a href="javascript:window.open('https://docs.spring.io/spring-data/jdbc/docs/1.0.5.RELEASE/api/org/springframework/data/relational/core/mapping/NamingStrategy.html');" target="_blank" rel="noopener noreferrer"><code class="notranslate">NamingStrategy</code> <i class="fa fa-external-link"></i></a> in your application context.</p>
</div>
</div>
<div class="sect3">
<h4 id="jdbc.entity-persistence.custom-table-name"><a class="anchor" href="#jdbc.entity-persistence.custom-table-name"></a>4.4.5. <code class="notranslate">Custom table names</code></h4>
<div class="paragraph">
<p>When the NamingStrategy does not matching on your database table names, you can customize the names with the <a href="javascript:window.open('https://docs.spring.io/spring-data/jdbc/docs/1.0.5.RELEASE/api/org/springframework/data/relational/core/mapping/Table.html');" target="_blank" rel="noopener noreferrer"><code class="notranslate">@Table</code> <i class="fa fa-external-link"></i></a> annotation. The element <code class="notranslate">value</code> of this annotation provides the custom table name. The following example maps the <code class="notranslate">MyEntity</code> class to the <code class="notranslate">CUSTOM_TABLE_NAME</code> table in the database:</p>
</div>
<div class="exampleblock">
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight notranslate"><code class="language-java" data-lang="java">@Table("CUSTOM_TABLE_NAME")
public class MyEntity {
    @Id
    Integer id;

    String name;
}</code></pre>
</div>
</div>
</div>
</div>
</div>
<div class="sect3">
<h4 id="jdbc.entity-persistence.custom-column-name"><a class="anchor" href="#jdbc.entity-persistence.custom-column-name"></a>4.4.6. <code class="notranslate">Custom column names</code></h4>
<div class="paragraph">
<p>When the NamingStrategy does not matching on your database column names, you can customize the names with the <a href="javascript:window.open('https://docs.spring.io/spring-data/jdbc/docs/1.0.5.RELEASE/api/org/springframework/data/relational/core/mapping/Column.html');" target="_blank" rel="noopener noreferrer"><code class="notranslate">@Column</code> <i class="fa fa-external-link"></i></a> annotation. The element <code class="notranslate">value</code> of this annotation provides the custom column name. The following example maps the <code class="notranslate">name</code> property of the <code class="notranslate">MyEntity</code> class to the <code class="notranslate">CUSTOM_COLUMN_NAME</code> column in the database:</p>
</div>
<div class="exampleblock">
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight notranslate"><code class="language-java" data-lang="java">public class MyEntity {
    @Id
    Integer id;

    @Column("CUSTOM_COLUMN_NAME")
    String name;
}</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<p>The <a href="javascript:window.open('https://docs.spring.io/spring-data/jdbc/docs/1.0.5.RELEASE/api/org/springframework/data/relational/core/mapping/Column.html');" target="_blank" rel="noopener noreferrer"><code class="notranslate">@Column</code> <i class="fa fa-external-link"></i></a> annotation can also be used on a reference type (one-to-one relationship) or on Sets, Lists, and Maps (one-to-many relationship) On all these types the <code class="notranslate">value</code> element of the annotation is used to provide a custom name for the foreign key column referencing the id column in the other table. In the following example the corresponding table for the <code class="notranslate">MySubEntity</code> class has a name column, and the id column of the <code class="notranslate">MyEntity</code> id for relationship reasons. The name of this <code class="notranslate">MySubEntity</code> class’s id column can also be customized with the <code class="notranslate">value</code> element of the <a href="javascript:window.open('https://docs.spring.io/spring-data/jdbc/docs/1.0.5.RELEASE/api/org/springframework/data/relational/core/mapping/Column.html');" target="_blank" rel="noopener noreferrer"><code class="notranslate">@Column</code> <i class="fa fa-external-link"></i></a> annotation:</p>
 </div>
<div class="exampleblock">
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight notranslate"><code class="language-java" data-lang="java">public class MyEntity {
    @Id
    Integer id;

    @Column("CUSTOM_COLUMN_NAME")
    Set&lt;MySubEntity&gt; name;
}

public class MySubEntity {
    String name;
}</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<p>When using <code class="notranslate">List</code> and <code class="notranslate">Map</code> you must have an additional column for the position of a dataset in the <code class="notranslate">List</code> or the key value of the entity in the <code class="notranslate">Map</code>. This additional column name may be customized with the <code class="notranslate">keyColumn</code> Element of the <a href="javascript:window.open('https://docs.spring.io/spring-data/jdbc/docs/1.0.5.RELEASE/api/org/springframework/data/relational/core/mapping/Column.html');" target="_blank" rel="noopener noreferrer"><code class="notranslate">@Column</code> <i class="fa fa-external-link"></i></a> annotation:</p>
</div>
<div class="exampleblock">
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight notranslate"><code class="language-java" data-lang="java">public class MyEntity {
    @Id
    Integer id;

    @Column(value = "CUSTOM_COLUMN_NAME", keyColumn = "CUSTOM_KEY_COLUMN_NAME")
    List&lt;MySubEntity&gt; name;
}

public class MySubEntity {
    String name;
}</code></pre>
</div>
</div>
</div>
</div>
</div>
<div class="sect3">
<h4 id="jdbc.entity-persistence.state-detection-strategies"><a class="anchor" href="#jdbc.entity-persistence.state-detection-strategies"></a>4.4.7. Entity State Detection Strategies</h4>
<div class="paragraph">
<p>The following table describes the strategies that Spring Data JDBC offers for detecting whether an entity is new:</p>
</div>
<table class="tableblock frame-all grid-all fit-content">
<caption class="title">
Table 2. Options for detection whether an entity is new in Spring Data JDBC
</caption>
<colgroup>
<col>
<col>
</colgroup>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">Id-Property inspection (the default)</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">By default, Spring Data JDBC inspects the identifier property of the given entity. If the identifier property is <code class="notranslate">null</code>, then the entity is assumed to be new. Otherwise, it is assumed to not be new.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">Implementing <code class="notranslate">Persistable</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">If an entity implements <code class="notranslate">Persistable</code>, Spring Data JDBC delegates the new detection to the <code class="notranslate">isNew(…)</code> method of the entity. See the <a href="javascript:window.open('https://docs.spring.io/spring-data/data-commons/docs/current/api/index.html?org/springframework/data/domain/Persistable.html');" target="_blank" rel="noopener noreferrer">Javadoc <i class="fa fa-external-link"></i></a> for details.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">Implementing <code class="notranslate">EntityInformation</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">You can customize the <code class="notranslate">EntityInformation</code> abstraction used in the <code class="notranslate">SimpleJdbcRepository</code> implementation by creating a subclass of <code class="notranslate">JdbcRepositoryFactory</code> and overriding the <code class="notranslate">getEntityInformation(…)</code> method. You then have to register the custom implementation of <code class="notranslate">JdbcRepositoryFactory</code> as a Spring bean. Note that this should rarely be necessary. See the <a href="javascript:window.open('https://docs.spring.io/spring-data/jdbc/docs/1.0.5.RELEASE/api/org/springframework/data/jdbc/repository/support/JdbcRepositoryFactory.html');" target="_blank" rel="noopener noreferrer">Javadoc <i class="fa fa-external-link"></i></a> for details.</p></td>
</tr>
</tbody>
</table>
</div>
<div class="sect3">
<h4 id="jdbc.entity-persistence.id-generation"><a class="anchor" href="#jdbc.entity-persistence.id-generation"></a>4.4.8. ID Generation</h4>
<div class="paragraph">
<p>Spring Data JDBC uses the ID to identify entities. The ID of an entity must be annotated with Spring Data’s <a href="javascript:window.open('https://docs.spring.io/spring-data/commons/docs/current/api/org/springframework/data/annotation/Id.html');" target="_blank" rel="noopener noreferrer"><code class="notranslate">@Id</code> <i class="fa fa-external-link"></i></a> annotation.</p>
</div>
<div class="paragraph">
<p>When your data base has an auto-increment column for the ID column, the generated value gets set in the entity after inserting it into the database.</p>
</div>
<div class="paragraph">
<p>One important constraint is that, after saving an entity, the entity must not be new any more. Note that whether an entity is new is part of the entity’s state. With auto-increment columns, this happens automatically, because the ID gets set by Spring Data with the value from the ID column. If you are not using auto-increment columns, you can use a <code class="notranslate">BeforeSave</code> listener, which sets the ID of the entity (covered later in this document).</p>
</div>
</div>
</div>
<div class="sect2">
<h3 id="jdbc.query-methods"><a class="anchor" href="#jdbc.query-methods"></a>4.5. Query Methods</h3>
<div class="paragraph">
<p>This section offers some specific information about the implementation and use of Spring Data JDBC.</p>
</div>
<div class="sect3">
<h4 id="jdbc.query-methods.strategies"><a class="anchor" href="#jdbc.query-methods.strategies"></a>4.5.1. Query Lookup Strategies</h4>
<div class="paragraph">
<p>The JDBC module supports defining a query manually only as a String in a <code class="notranslate">@Query</code> annotation. Deriving a query from the name of the method is currently not supported.</p>
</div>
</div>
<div class="sect3">
<h4 id="jdbc.query-methods.at-query"><a class="anchor" href="#jdbc.query-methods.at-query"></a>4.5.2. Using <code class="notranslate">@Query</code></h4>
<div class="paragraph">
<p>The following example shows how to use <code class="notranslate">@Query</code> to declare a query method:</p>
</div>
<div class="exampleblock">
<div class="title">
Example 54. Declare a query method by using @Query
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight notranslate"><code class="language-java" data-lang="java">public interface UserRepository extends CrudRepository&lt;User, Long&gt; {

  @Query("select firstName, lastName from User u where u.emailAddress = :email")
  User findByEmailAddress(@Param("email") String email);
}</code></pre>
</div>
</div>
</div>
</div>
<div class="admonitionblock note">
<table>
<tbody>
<tr>
<td class="icon"> <i class="fa icon-note" title="Note"></i> </td>
<td class="content"> Spring fully supports Java 8’s parameter name discovery based on the <code class="notranslate">-parameters</code> compiler flag. By using this flag in your build as an alternative to debug information, you can omit the <code class="notranslate">@Param</code> annotation for named parameters. </td>
</tr>
</tbody>
</table>
</div>
<div class="admonitionblock note">
<table>
<tbody>
<tr>
<td class="icon"> <i class="fa icon-note" title="Note"></i> </td>
<td class="content"> Spring Data JDBC supports only named parameters. </td>
</tr>
</tbody>
</table>
</div>
<div class="sect4">
<h5 id="jdbc.query-methods.at-query.custom-rowmapper"><a class="anchor" href="#jdbc.query-methods.at-query.custom-rowmapper"></a>Custom <code class="notranslate">RowMapper</code></h5>
<div class="paragraph">
<p>You can configure which <code class="notranslate">RowMapper</code> to use, either by using the <code class="notranslate">@Query(rowMapperClass = ….)</code> or by registering a <code class="notranslate">RowMapperMap</code> bean and registering a <code class="notranslate">RowMapper</code> per method return type. The following example shows how to register <code class="notranslate">RowMappers</code>:</p>
</div>
<div class="exampleblock">
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight notranslate"><code class="language-java" data-lang="java">@Bean
RowMapperMap rowMappers() {
	return new ConfigurableRowMapperMap() //
		.register(Person.class, new PersonRowMapper()) //
		.register(Address.class, new AddressRowMapper());
}</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<p>When determining which <code class="notranslate">RowMapper</code> to use for a method, the following steps are followed, based on the return type of the method:</p>
</div>
<div class="olist arabic">
<ol class="arabic">
<li> <p>If the type is a simple type, no <code class="notranslate">RowMapper</code> is used.</p>
<div class="paragraph">
<p>Instead, the query is expected to return a single row with a single column, and a conversion to the return type is applied to that value.</p>
</div> </li>
<li> <p>The entity classes in the <code class="notranslate">RowMapperMap</code> are iterated until one is found that is a superclass or interface of the return type in question. The <code class="notranslate">RowMapper</code> registered for that class is used.</p>
<div class="paragraph">
<p>Iterating happens in the order of registration, so make sure to register more general types after specific ones.</p>
</div> </li>
</ol>
</div>
<div class="paragraph">
<p>If applicable, wrapper types such as collections or <code class="notranslate">Optional</code> are unwrapped. Thus, a return type of <code class="notranslate">Optional&lt;Person&gt;</code> uses the <code class="notranslate">Person</code> type in the preceding process.</p>
</div>
</div>
<div class="sect4">
<h5 id="jdbc.query-methods.at-query.modifying"><a class="anchor" href="#jdbc.query-methods.at-query.modifying"></a>Modifying Query</h5>
<div class="paragraph">
<p>You can mark a query as being a modifying query by using the <code class="notranslate">@Modifying</code> on query method, as the following example shows:</p>
</div>
<div class="exampleblock">
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight notranslate"><code class="language-java" data-lang="java">@Modifying
@Query("UPDATE DUMMYENTITY SET name = :name WHERE id = :id")
boolean updateName(@Param("id") Long id, @Param("name") String name);</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<p>You can specify the following return types:</p>
</div>
<div class="ulist">
<ul>
<li> <p><code class="notranslate">void</code></p> </li>
<li> <p><code class="notranslate">int</code> (updated record count)</p> </li>
<li> <p><code class="notranslate">boolean</code>(whether a record was updated)</p> </li>
</ul>
</div>
</div>
</div>
</div>
<div class="sect2">
<h3 id="jdbc.mybatis"><a class="anchor" href="#jdbc.mybatis"></a>4.6. MyBatis Integration</h3>
<div class="paragraph">
<p>For each operation in <code class="notranslate">CrudRepository</code>, Spring Data JDBC runs multiple statements. If there is a <a href="javascript:window.open('https://github.com/mybatis/mybatis-3/blob/master/src/main/java/org/apache/ibatis/session/SqlSessionFactory.java');" target="_blank" rel="noopener noreferrer"><code class="notranslate">SqlSessionFactory</code> <i class="fa fa-external-link"></i></a> in the application context, Spring Data checks, for each step, whether the <code class="notranslate">SessionFactory</code> offers a statement. If one is found, that statement (including its configured mapping to an entity) is used.</p>
</div>
<div class="paragraph">
<p>The name of the statement is constructed by concatenating the fully qualified name of the entity type with <code class="notranslate">Mapper.</code> and a <code class="notranslate">String</code> determining the kind of statement. For example, if an instance of <code class="notranslate">org.example.User</code> is to be inserted, Spring Data JDBC looks for a statement named <code class="notranslate">org.example.UserMapper.insert</code>.</p>
</div>
<div class="paragraph">
<p>When the statement is run, an instance of [<code class="notranslate">MyBatisContext</code>] gets passed as an argument, which makes various arguments available to the statement.</p>
</div>
<div class="paragraph">
<p>The following table describes the available MyBatis statements:</p>
</div>
<table class="tableblock frame-all grid-all stretch">
<colgroup>
<col style="width: 25%;">
<col style="width: 25%;">
<col style="width: 25%;">
<col style="width: 25%;">
</colgroup>
<thead>
<tr>
<th class="tableblock halign-left valign-top">Name</th>
<th class="tableblock halign-left valign-top">Purpose</th>
<th class="tableblock halign-left valign-top">CrudRepository methods that might trigger this statement</th>
<th class="tableblock halign-left valign-top">Attributes available in the <code class="notranslate">MyBatisContext</code></th>
</tr>
</thead>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code class="notranslate">insert</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Inserts a single entity. This also applies for entities referenced by the aggregate root.</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code class="notranslate">save</code>, <code class="notranslate">saveAll</code>.</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code class="notranslate">getInstance</code>: the instance to be saved</p> <p class="tableblock"><code class="notranslate">getDomainType</code>: The type of the entity to be saved.</p> <p class="tableblock"><code class="notranslate">get(&lt;key&gt;)</code>: ID of the referencing entity, where <code class="notranslate">&lt;key&gt;</code> is the name of the back reference column provided by the <code class="notranslate">NamingStrategy</code>.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code class="notranslate">update</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Updates a single entity. This also applies for entities referenced by the aggregate root.</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code class="notranslate">save</code>, <code class="notranslate">saveAll</code>.</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code class="notranslate">getInstance</code>: The instance to be saved</p> <p class="tableblock"><code class="notranslate">getDomainType</code>: The type of the entity to be saved.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code class="notranslate">delete</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Deletes a single entity.</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code class="notranslate">delete</code>, <code class="notranslate">deleteById</code>.</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code class="notranslate">getId</code>: The ID of the instance to be deleted</p> <p class="tableblock"><code class="notranslate">getDomainType</code>: The type of the entity to be deleted.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code class="notranslate">deleteAll-&lt;propertyPath&gt;</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Deletes all entities referenced by any aggregate root of the type used as prefix with the given property path. Note that the type used for prefixing the statement name is the name of the aggregate root, not the one of the entity to be deleted.</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code class="notranslate">deleteAll</code>.</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code class="notranslate">getDomainType</code>: The types of the entities to be deleted.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code class="notranslate">deleteAll</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Deletes all aggregate roots of the type used as the prefix</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code class="notranslate">deleteAll</code>.</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code class="notranslate">getDomainType</code>: The type of the entities to be deleted.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code class="notranslate">delete-&lt;propertyPath&gt;</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Deletes all entities referenced by an aggregate root with the given propertyPath</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code class="notranslate">deleteById</code>.</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code class="notranslate">getId</code>: The ID of the aggregate root for which referenced entities are to be deleted.</p> <p class="tableblock"><code class="notranslate">getDomainType</code>: The type of the entities to be deleted.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code class="notranslate">findById</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Selects an aggregate root by ID</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code class="notranslate">findById</code>.</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code class="notranslate">getId</code>: The ID of the entity to load.</p> <p class="tableblock"><code class="notranslate">getDomainType</code>: The type of the entity to load.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code class="notranslate">findAll</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Select all aggregate roots</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code class="notranslate">findAll</code>.</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code class="notranslate">getDomainType</code>: The type of the entity to load.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code class="notranslate">findAllById</code></p></td>
 <td class="tableblock halign-left valign-top"><p class="tableblock">Select a set of aggregate roots by ID values</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code class="notranslate">findAllById</code>.</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code class="notranslate">getId</code>: A list of ID values of the entities to load.</p> <p class="tableblock"><code class="notranslate">getDomainType</code>: The type of the entity to load.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code class="notranslate">findAllByProperty-&lt;propertyName&gt;</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Select a set of entities that is referenced by another entity. The type of the referencing entity is used for the prefix. The referenced entities type is used as the suffix.</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">All <code class="notranslate">find*</code> methods.</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code class="notranslate">getId</code>: The ID of the entity referencing the entities to be loaded.</p> <p class="tableblock"><code class="notranslate">getDomainType</code>: The type of the entity to load.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code class="notranslate">count</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Count the number of aggregate root of the type used as prefix</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code class="notranslate">count</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code class="notranslate">getDomainType</code>: The type of aggregate roots to count.</p></td>
</tr>
</tbody>
</table>
</div>
<div class="sect2">
<h3 id="jdbc.events"><a class="anchor" href="#jdbc.events"></a>4.7. Events</h3>
<div class="paragraph">
<p>Spring Data JDBC triggers events that get published to any matching <code class="notranslate">ApplicationListener</code> in the application context. For example, the following listener gets invoked before an aggregate gets saved:</p>
</div>
<div class="exampleblock">
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight notranslate"><code class="language-java" data-lang="java">@Bean
public ApplicationListener&lt;BeforeSave&gt; timeStampingSaveTime() {

	return event -&gt; {

		Object entity = event.getEntity();
		if (entity instanceof Category) {
			Category category = (Category) entity;
			category.timeStamp();
		}
	};
}</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<p>The following table describes the available events:</p>
</div>
<table class="tableblock frame-all grid-all stretch">
<caption class="title">
Table 3. Available events
</caption>
<colgroup>
<col style="width: 50%;">
<col style="width: 50%;">
</colgroup>
<thead>
<tr>
<th class="tableblock halign-left valign-top">Event</th>
<th class="tableblock halign-left valign-top">When It Is Published</th>
</tr>
</thead>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="javascript:window.open('https://docs.spring.io/spring-data/jdbc/docs/1.0.5.RELEASE/api/org/springframework/data/relational/core/mapping/event/BeforeDeleteEvent.html');" target="_blank" rel="noopener noreferrer"><code class="notranslate">BeforeDeleteEvent</code> <i class="fa fa-external-link"></i></a></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Before an aggregate root gets deleted.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="javascript:window.open('https://docs.spring.io/spring-data/jdbc/docs/1.0.5.RELEASE/api/org/springframework/data/relational/core/mapping/event/AfterDeleteEvent.html');" target="_blank" rel="noopener noreferrer"><code class="notranslate">AfterDeleteEvent</code> <i class="fa fa-external-link"></i></a></p></td>
</tr>
</tbody>
</table>
</div>
</div>
</div></div>
</div>
</section>
<div class="right-sidebar">
<div class="affix"><ins class="adsbygoogle" style="display:block" data-ad-client="ca-pub-6108808167664152" data-ad-slot="3102929424" data-ad-format="auto" data-full-width-responsive="true"></ins>
<script>
     (adsbygoogle = window.adsbygoogle || []).push({});
</script></div>
</div>
</div>
<div class="ft">
<a href="#toolbar-title" id="anchorNavigationExGoTop"><i class="fa fa-arrow-up"></i></a>
<footer class="footer">
<div class="footer__container--normal">
<img alt="扫码关注公众号" title="扫码关注公众号" src="static/picture/qr-code.png" width="170" height="170">
<div class="footer__description--normal">
<p class="paragraph footer__author--normal">Docs4dev<sup class="super">&#xAE;</sup>
</p>
<p class="paragraph footer__quote&#45;&#45;normal">
如果你在使用过程中遇到任何问题，可以在 <a href="javascript:window.open('https://github.com/docs4dev/docs4dev-issues');" target="_blank" rel="noopener noreferrer">这里<i class="fa fa-external-link"></i></a> 提issue。
</p>
<div class="footer__main--normal">
<p class="paragraph footer__main__paragraph--normal copyright" style="color: #666 !important;">
<a href="javascript:window.open('https://beian.miit.gov.cn/');">
蜀ICP备14021783号-6
</a>
</p>
<p class="paragraph footer__main__paragraph--normal copyright" style="color: #666 !important;">
Copyright &#xA9; Docs4dev all
right reserved, powered by <a href="index2.html" target="_blank">Docs4dev</a></p>
</div>
</div>
</div>
<div class="box__issues">
</div>
</footer>
</div>
</div>
</div>
</div>
</div>
<script>
  var hasToc = true;
  /*  var downloadable = /!*false*!/ false;
    var editable = /!*false*!/ false;
    var code = /!*"spring-data-jdbc"*!/ false;
    var version = /!*"1.0.5.RELEASE"*!/ false;
    var type = /!*"reference"*!/ false;
    var lang = /!*"en"*!/ 'en';
    //edit link
    require(["gitbook", "jQuery"], function (gitbook, $) {
      gitbook.events.bind('start', function (e, config) {
        // Add edit toolbar to left
        var chapterId = /!*16330*!/ 0;
        if (downloadable) {
          gitbook.toolbar.createButton({
            icon: 'fa fa-download',
            text: '下载',
            onClick: function () {
              window.open('/download?code=' + code + '&version=' + version + '&type=' + type + '&lang=' + lang);
            }
          });
        }
        if (editable) {
          gitbook.toolbar.createButton({
            icon: 'fa fa-edit',
            text: '编辑此页',
            onClick: function () {
              window.open('/docs/edit?chapterId=' + chapterId + '&lang=' + lang);
            }
          });
        }
      });
    });*/
</script>
<script>
    var code = "spring-data-jdbc";
    var lang = "en";
  </script>

<script src="static/js/autocomplete-js.js"></script>
<script src="static/js/app.min.js"></script>
<script src="static/js/search.min.js"></script>
</body>
</html>
